diff --git a/api/current.txt b/api/current.txt
index ee01fb8840869..93884aae96597 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -6105,6 +6105,7 @@ package android.app.backup {
method public void onCreate();
method public void onDestroy();
method public void onFullBackup(android.app.backup.FullBackupDataOutput) throws java.io.IOException;
+ method public void onQuotaExceeded(long, long);
method public abstract void onRestore(android.app.backup.BackupDataInput, int, android.os.ParcelFileDescriptor) throws java.io.IOException;
method public void onRestoreFile(android.os.ParcelFileDescriptor, long, java.io.File, int, long, long) throws java.io.IOException;
method public void onRestoreFinished();
diff --git a/api/system-current.txt b/api/system-current.txt
index 31df3b2f54672..3fc6437f4668a 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -6254,6 +6254,7 @@ package android.app.backup {
method public void onCreate();
method public void onDestroy();
method public void onFullBackup(android.app.backup.FullBackupDataOutput) throws java.io.IOException;
+ method public void onQuotaExceeded(long, long);
method public abstract void onRestore(android.app.backup.BackupDataInput, int, android.os.ParcelFileDescriptor) throws java.io.IOException;
method public void onRestoreFile(android.os.ParcelFileDescriptor, long, java.io.File, int, long, long) throws java.io.IOException;
method public void onRestoreFinished();
@@ -6316,6 +6317,7 @@ package android.app.backup {
field public static final int ERROR_PACKAGE_NOT_FOUND = -2002; // 0xfffff82e
field public static final int ERROR_TRANSPORT_ABORTED = -1000; // 0xfffffc18
field public static final int ERROR_TRANSPORT_PACKAGE_REJECTED = -1002; // 0xfffffc16
+ field public static final int ERROR_TRANSPORT_QUOTA_EXCEEDED = -1005; // 0xfffffc13
field public static final int SUCCESS = 0; // 0x0
}
@@ -6348,6 +6350,7 @@ package android.app.backup {
method public int finishBackup();
method public void finishRestore();
method public android.app.backup.RestoreSet[] getAvailableRestoreSets();
+ method public long getBackupQuota(java.lang.String, boolean);
method public android.os.IBinder getBinder();
method public long getCurrentRestoreSet();
method public int getNextFullRestoreDataChunk(android.os.ParcelFileDescriptor);
@@ -6373,6 +6376,7 @@ package android.app.backup {
field public static final int TRANSPORT_NOT_INITIALIZED = -1001; // 0xfffffc17
field public static final int TRANSPORT_OK = 0; // 0x0
field public static final int TRANSPORT_PACKAGE_REJECTED = -1002; // 0xfffffc16
+ field public static final int TRANSPORT_QUOTA_EXCEEDED = -1005; // 0xfffffc13
}
public class FileBackupHelper extends android.app.backup.FileBackupHelperBase implements android.app.backup.BackupHelper {
diff --git a/api/test-current.txt b/api/test-current.txt
index 19b07f4715b95..e2ad7612f64a1 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -6107,6 +6107,7 @@ package android.app.backup {
method public void onCreate();
method public void onDestroy();
method public void onFullBackup(android.app.backup.FullBackupDataOutput) throws java.io.IOException;
+ method public void onQuotaExceeded(long, long);
method public abstract void onRestore(android.app.backup.BackupDataInput, int, android.os.ParcelFileDescriptor) throws java.io.IOException;
method public void onRestoreFile(android.os.ParcelFileDescriptor, long, java.io.File, int, long, long) throws java.io.IOException;
method public void onRestoreFinished();
diff --git a/core/java/android/app/IBackupAgent.aidl b/core/java/android/app/IBackupAgent.aidl
index fe8e2287ccd26..eda960385acac 100644
--- a/core/java/android/app/IBackupAgent.aidl
+++ b/core/java/android/app/IBackupAgent.aidl
@@ -104,6 +104,27 @@ oneway interface IBackupAgent {
*/
void doMeasureFullBackup(int token, IBackupManager callbackBinder);
+ /**
+ * Tells the application agent that the backup data size exceeded current transport quota.
+ * Later calls to {@link #onBackup(ParcelFileDescriptor, BackupDataOutput, ParcelFileDescriptor)}
+ * and {@link #onFullBackup(FullBackupDataOutput)} could use this information
+ * to reduce backup size under the limit.
+ * However, the quota can change, so do not assume that the value passed in here is absolute,
+ * similarly all subsequent backups should not be restricted to this size.
+ * This callback will be invoked before data has been put onto the wire in a preflight check,
+ * so it is relatively inexpensive to hit your quota.
+ * Apps that hit quota repeatedly without dealing with it can be subject to having their backup
+ * schedule reduced.
+ * The {@code quotaBytes} is a loose guideline b/c of metadata added by the backupmanager
+ * so apps should be more aggressive in trimming their backup set.
+ *
+ * @param backupDataBytes Expected or already processed amount of data.
+ * Could be less than total backup size if backup process was interrupted
+ * before finish of processing all backup data.
+ * @param quotaBytes Current amount of backup data that is allowed for the app.
+ */
+ void doQuotaExceeded(long backupDataBytes, long quotaBytes);
+
/**
* Restore a single "file" to the application. The file was typically obtained from
* a full-backup dataset. The agent reads 'size' bytes of file content
diff --git a/core/java/android/app/backup/BackupAgent.java b/core/java/android/app/backup/BackupAgent.java
index aa4a631ea76a6..63f142552c282 100644
--- a/core/java/android/app/backup/BackupAgent.java
+++ b/core/java/android/app/backup/BackupAgent.java
@@ -381,6 +381,28 @@ public abstract class BackupAgent extends ContextWrapper {
}
}
+ /**
+ * Tells the application agent that the backup data size exceeded current transport quota.
+ * Later calls to {@link #onBackup(ParcelFileDescriptor, BackupDataOutput, ParcelFileDescriptor)}
+ * and {@link #onFullBackup(FullBackupDataOutput)} could use this information
+ * to reduce backup size under the limit.
+ * However, the quota can change, so do not assume that the value passed in here is absolute,
+ * similarly all subsequent backups should not be restricted to this size.
+ * This callback will be invoked before data has been put onto the wire in a preflight check,
+ * so it is relatively inexpensive to hit your quota.
+ * Apps that hit quota repeatedly without dealing with it can be subject to having their backup
+ * schedule reduced.
+ * The {@code quotaBytes} is a loose guideline b/c of metadata added by the backupmanager
+ * so apps should be more aggressive in trimming their backup set.
+ *
+ * @param backupDataBytes Expected or already processed amount of data.
+ * Could be less than total backup size if backup process was interrupted
+ * before finish of processing all backup data.
+ * @param quotaBytes Current amount of backup data that is allowed for the app.
+ */
+ public void onQuotaExceeded(long backupDataBytes, long quotaBytes) {
+ }
+
/**
* Check whether the xml yielded any tag for the provided domainToken.
* If so, perform a {@link #fullBackupFileTree} which backs up the file or recurses if the path
@@ -955,6 +977,21 @@ public abstract class BackupAgent extends ContextWrapper {
public void fail(String message) {
getHandler().post(new FailRunnable(message));
}
+
+ @Override
+ public void doQuotaExceeded(long backupDataBytes, long quotaBytes) {
+ long ident = Binder.clearCallingIdentity();
+ try {
+ BackupAgent.this.onQuotaExceeded(backupDataBytes, quotaBytes);
+ } catch (Exception e) {
+ Log.d(TAG, "onQuotaExceeded(" + BackupAgent.this.getClass().getName() + ") threw",
+ e);
+ throw e;
+ } finally {
+ waitForSharedPrefs();
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
}
static class FailRunnable implements Runnable {
diff --git a/core/java/android/app/backup/BackupManager.java b/core/java/android/app/backup/BackupManager.java
index c27eaa4f59bfa..ff62b7cffedfa 100644
--- a/core/java/android/app/backup/BackupManager.java
+++ b/core/java/android/app/backup/BackupManager.java
@@ -109,6 +109,16 @@ public class BackupManager {
public static final int ERROR_TRANSPORT_PACKAGE_REJECTED =
BackupTransport.TRANSPORT_PACKAGE_REJECTED;
+ /**
+ * Returned when the transport reject the attempt to backup because
+ * backup data size exceeded current quota limit for this package.
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final int ERROR_TRANSPORT_QUOTA_EXCEEDED =
+ BackupTransport.TRANSPORT_QUOTA_EXCEEDED;
+
/**
* The {@link BackupAgent} for the requested package failed for some reason
* and didn't provide appropriate backup data.
diff --git a/core/java/android/app/backup/BackupTransport.java b/core/java/android/app/backup/BackupTransport.java
index aca115f29e78f..ac23b6888dd05 100644
--- a/core/java/android/app/backup/BackupTransport.java
+++ b/core/java/android/app/backup/BackupTransport.java
@@ -49,6 +49,7 @@ public class BackupTransport {
public static final int TRANSPORT_PACKAGE_REJECTED = -1002;
public static final int AGENT_ERROR = -1003;
public static final int AGENT_UNKNOWN = -1004;
+ public static final int TRANSPORT_QUOTA_EXCEEDED = -1005;
// Indicates that operation was initiated by user, not a scheduled one.
// Transport should ignore its own moratoriums for call with this flag set.
@@ -494,6 +495,18 @@ public class BackupTransport {
return true;
}
+ /**
+ * Ask the transport about current quota for backup size of the package.
+ *
+ * @param packageName ID of package to provide the quota.
+ * @param isFullBackup If set, transport should return limit for full data backup, otherwise
+ * for key-value backup.
+ * @return Current limit on full data backup size in bytes.
+ */
+ public long getBackupQuota(String packageName, boolean isFullBackup) {
+ return Long.MAX_VALUE;
+ }
+
// ------------------------------------------------------------------------------------
// Full restore interfaces
@@ -676,6 +689,11 @@ public class BackupTransport {
return BackupTransport.this.isAppEligibleForBackup(targetPackage, isFullBackup);
}
+ @Override
+ public long getBackupQuota(String packageName, boolean isFullBackup) {
+ return BackupTransport.this.getBackupQuota(packageName, isFullBackup);
+ }
+
@Override
public int getNextFullRestoreDataChunk(ParcelFileDescriptor socket) {
return BackupTransport.this.getNextFullRestoreDataChunk(socket);
diff --git a/core/java/com/android/internal/backup/IBackupTransport.aidl b/core/java/com/android/internal/backup/IBackupTransport.aidl
index 444dbfa71e8c1..98f5bea4a8699 100644
--- a/core/java/com/android/internal/backup/IBackupTransport.aidl
+++ b/core/java/com/android/internal/backup/IBackupTransport.aidl
@@ -249,6 +249,16 @@ interface IBackupTransport {
*/
boolean isAppEligibleForBackup(in PackageInfo targetPackage, boolean isFullBackup);
+ /**
+ * Ask the transport about current quota for backup size of the package.
+ *
+ * @param packageName ID of package to provide the quota.
+ * @param isFullBackup If set, transport should return limit for full data backup, otherwise
+ * for key-value backup.
+ * @return Current limit on full data backup size in bytes.
+ */
+ long getBackupQuota(String packageName, boolean isFullBackup);
+
// full restore stuff
/**
diff --git a/core/java/com/android/internal/backup/LocalTransport.java b/core/java/com/android/internal/backup/LocalTransport.java
index 22d35f204de8f..8cdfc640247d5 100644
--- a/core/java/com/android/internal/backup/LocalTransport.java
+++ b/core/java/com/android/internal/backup/LocalTransport.java
@@ -71,6 +71,9 @@ public class LocalTransport extends BackupTransport {
// The currently-active restore set always has the same (nonzero!) token
private static final long CURRENT_SET_TOKEN = 1;
+ // Full backup size quota is set to reasonable value.
+ private static final long FULL_BACKUP_SIZE_QUOTA = 25 * 1024 * 1024;
+
private Context mContext;
private File mDataDir = new File(Environment.getDownloadCacheDirectory(), "backup");
private File mCurrentSetDir = new File(mDataDir, Long.toString(CURRENT_SET_TOKEN));
@@ -90,6 +93,7 @@ public class LocalTransport extends BackupTransport {
private FileInputStream mSocketInputStream;
private BufferedOutputStream mFullBackupOutputStream;
private byte[] mFullBackupBuffer;
+ private long mFullBackupSize;
private FileInputStream mCurFullRestoreStream;
private FileOutputStream mFullRestoreSocketStream;
@@ -314,8 +318,13 @@ public class LocalTransport extends BackupTransport {
@Override
public int checkFullBackupSize(long size) {
+ int result = TRANSPORT_OK;
// Decline zero-size "backups"
- final int result = (size > 0) ? TRANSPORT_OK : TRANSPORT_PACKAGE_REJECTED;
+ if (size <= 0) {
+ result = TRANSPORT_PACKAGE_REJECTED;
+ } else if (size > FULL_BACKUP_SIZE_QUOTA) {
+ result = TRANSPORT_QUOTA_EXCEEDED;
+ }
if (result != TRANSPORT_OK) {
if (DEBUG) {
Log.v(TAG, "Declining backup of size " + size);
@@ -339,6 +348,7 @@ public class LocalTransport extends BackupTransport {
// sure to dup() our own copy of the socket fd. Transports which run in
// their own processes must not do this.
try {
+ mFullBackupSize = 0;
mSocket = ParcelFileDescriptor.dup(socket.getFileDescriptor());
mSocketInputStream = new FileInputStream(mSocket.getFileDescriptor());
} catch (IOException e) {
@@ -359,6 +369,11 @@ public class LocalTransport extends BackupTransport {
return TRANSPORT_ERROR;
}
+ mFullBackupSize += numBytes;
+ if (mFullBackupSize > FULL_BACKUP_SIZE_QUOTA) {
+ return TRANSPORT_QUOTA_EXCEEDED;
+ }
+
if (numBytes > mFullBackupBuffer.length) {
mFullBackupBuffer = new byte[numBytes];
}
@@ -699,4 +714,8 @@ public class LocalTransport extends BackupTransport {
return TRANSPORT_OK;
}
+ @Override
+ public long getBackupQuota(String packageName, boolean isFullBackup) {
+ return isFullBackup ? FULL_BACKUP_SIZE_QUOTA : Long.MAX_VALUE;
+ }
}
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index 46198b0ccc5b8..0513e53b29470 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -3168,8 +3168,9 @@ public class BackupManagerService {
ParcelFileDescriptor backupData = null;
mStatus = BackupTransport.TRANSPORT_OK;
+ long size = 0;
try {
- int size = (int) mBackupDataName.length();
+ size = mBackupDataName.length();
if (size > 0) {
if (mStatus == BackupTransport.TRANSPORT_OK) {
backupData = ParcelFileDescriptor.open(mBackupDataName,
@@ -3214,6 +3215,10 @@ public class BackupManagerService {
sendBackupOnResult(mObserver, pkgName,
BackupManager.ERROR_TRANSPORT_PACKAGE_REJECTED);
EventLogTags.writeBackupAgentFailure(pkgName, "Transport rejected");
+ } else if (mStatus == BackupTransport.TRANSPORT_QUOTA_EXCEEDED) {
+ sendBackupOnResult(mObserver, pkgName,
+ BackupManager.ERROR_TRANSPORT_QUOTA_EXCEEDED);
+ EventLog.writeEvent(EventLogTags.BACKUP_QUOTA_EXCEEDED, pkgName);
} else {
// Actual transport-level failure to communicate the data to the backend
sendBackupOnResult(mObserver, pkgName, BackupManager.ERROR_TRANSPORT_ABORTED);
@@ -3234,6 +3239,20 @@ public class BackupManagerService {
// 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_QUOTA_EXCEEDED) {
+ if (MORE_DEBUG) {
+ Slog.d(TAG, "Package " + mCurrentPackage.packageName +
+ " hit quota limit on k/v backup");
+ }
+ if (mAgentBinder != null) {
+ try {
+ long quota = mTransport.getBackupQuota(mCurrentPackage.packageName, false);
+ mAgentBinder.doQuotaExceeded(size, quota);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Unable to contact backup agent for quota exceeded");
+ }
+ }
+ nextState = (mQueue.isEmpty()) ? BackupState.FINAL : BackupState.RUNNING_QUEUE;
} else {
// Any other error here indicates a transport-level failure. That means
// we need to halt everything and reschedule everything for next time.
@@ -3476,6 +3495,7 @@ public class BackupManagerService {
OutputStream mOutput;
FullBackupPreflight mPreflightHook;
IFullBackupRestoreObserver mObserver;
+ IBackupAgent mAgent;
File mFilesDir;
File mManifestFile;
File mMetadataFile;
@@ -3562,14 +3582,14 @@ public class BackupManagerService {
int result = BackupTransport.TRANSPORT_OK;
Slog.d(TAG, "Binding to full backup agent : " + pkg.packageName);
- IBackupAgent agent = bindToAgentSynchronous(pkg.applicationInfo,
+ mAgent = bindToAgentSynchronous(pkg.applicationInfo,
IApplicationThread.BACKUP_MODE_FULL);
- if (agent != null) {
+ if (mAgent != null) {
ParcelFileDescriptor[] pipes = null;
try {
// Call the preflight hook, if any
if (mPreflightHook != null) {
- result = mPreflightHook.preflightFullBackup(pkg, agent);
+ result = mPreflightHook.preflightFullBackup(pkg, mAgent);
if (MORE_DEBUG) {
Slog.v(TAG, "preflight returned " + result);
}
@@ -3592,7 +3612,7 @@ public class BackupManagerService {
UserHandle.USER_SYSTEM);
final int token = generateToken();
- FullBackupRunner runner = new FullBackupRunner(pkg, agent, pipes[1],
+ FullBackupRunner runner = new FullBackupRunner(pkg, mAgent, pipes[1],
token, sendApk, !isSharedStorage, widgetBlob);
pipes[1].close(); // the runner has dup'd it
pipes[1] = null;
@@ -3640,6 +3660,16 @@ public class BackupManagerService {
return result;
}
+ public void sendQuotaExceeded(final long backupDataBytes, final long quotaBytes) {
+ if (mAgent != null) {
+ try {
+ mAgent.doQuotaExceeded(backupDataBytes, quotaBytes);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Remote exception while telling agent about quota exceeded");
+ }
+ }
+ }
+
private void writeApkToBackup(PackageInfo pkg, FullBackupDataOutput output) {
// Forward-locked apps, system-bundled .apks, etc are filtered out before we get here
// TODO: handle backing up split APKs
@@ -4344,6 +4374,15 @@ public class BackupManagerService {
}
} while (nRead > 0 && result == BackupTransport.TRANSPORT_OK);
+ if (result == BackupTransport.TRANSPORT_QUOTA_EXCEEDED) {
+ long quota = transport.getBackupQuota(currentPackage.packageName, true);
+ if (MORE_DEBUG) {
+ Slog.d(TAG, "Package hit quota limit " + currentPackage.packageName
+ + ": " + totalRead + " of " + quota);
+ }
+ backupRunner.sendQuotaExceeded(totalRead, quota);
+ }
+
// If we've lost our running criteria, tell the transport to cancel
// and roll back this (partial) backup payload; otherwise tell it
// that we've reached the clean finish state.
@@ -4387,6 +4426,8 @@ public class BackupManagerService {
}
if (result == BackupTransport.TRANSPORT_PACKAGE_REJECTED) {
+ sendBackupOnResult(mBackupObserver, currentPackage.packageName,
+ BackupManager.ERROR_TRANSPORT_PACKAGE_REJECTED);
if (DEBUG) {
Slog.i(TAG, "Transport rejected backup of "
+ currentPackage.packageName
@@ -4394,35 +4435,40 @@ public class BackupManagerService {
}
EventLog.writeEvent(EventLogTags.FULL_BACKUP_AGENT_FAILURE,
currentPackage.packageName, "transport rejected");
- sendBackupOnResult(mBackupObserver, currentPackage.packageName,
- BackupManager.ERROR_TRANSPORT_PACKAGE_REJECTED);
// do nothing, clean up, and continue looping
+ } else if (result == BackupTransport.TRANSPORT_QUOTA_EXCEEDED) {
+ sendBackupOnResult(mBackupObserver, currentPackage.packageName,
+ BackupManager.ERROR_TRANSPORT_QUOTA_EXCEEDED);
+ Slog.w(TAG, "Transport quota exceeded; aborting backup: " + result);
+ EventLog.writeEvent(EventLogTags.FULL_BACKUP_QUOTA_EXCEEDED,
+ currentPackage.packageName);
+ return;
} else if (result != BackupTransport.TRANSPORT_OK) {
- Slog.w(TAG, "Transport failed; aborting backup: " + result);
- EventLog.writeEvent(EventLogTags.FULL_BACKUP_TRANSPORT_FAILURE);
sendBackupOnResult(mBackupObserver, currentPackage.packageName,
BackupManager.ERROR_TRANSPORT_ABORTED);
+ Slog.w(TAG, "Transport failed; aborting backup: " + result);
+ EventLog.writeEvent(EventLogTags.FULL_BACKUP_TRANSPORT_FAILURE);
return;
} else {
// Success!
+ sendBackupOnResult(mBackupObserver, currentPackage.packageName,
+ BackupManager.SUCCESS);
EventLog.writeEvent(EventLogTags.FULL_BACKUP_SUCCESS,
currentPackage.packageName);
logBackupComplete(currentPackage.packageName);
- sendBackupOnResult(mBackupObserver, currentPackage.packageName,
- BackupManager.SUCCESS);
}
cleanUpPipes(transportPipes);
cleanUpPipes(enginePipes);
currentPackage = null;
}
+ sendBackupFinished(mBackupObserver, BackupManager.SUCCESS);
if (DEBUG) {
Slog.i(TAG, "Full backup completed.");
}
- sendBackupFinished(mBackupObserver, BackupManager.SUCCESS);
} catch (Exception e) {
- Slog.w(TAG, "Exception trying full transport backup", e);
sendBackupFinished(mBackupObserver, BackupManager.ERROR_TRANSPORT_ABORTED);
+ Slog.w(TAG, "Exception trying full transport backup", e);
} finally {
cleanUpPipes(transportPipes);
cleanUpPipes(enginePipes);
@@ -4503,6 +4549,14 @@ public class BackupManagerService {
}
result = mTransport.checkFullBackupSize(totalSize);
+ if (result == BackupTransport.TRANSPORT_QUOTA_EXCEEDED) {
+ final long quota = mTransport.getBackupQuota(pkg.packageName, true);
+ if (MORE_DEBUG) {
+ Slog.d(TAG, "Package hit quota limit on preflight " +
+ pkg.packageName + ": " + totalSize + " of " + quota);
+ }
+ agent.doQuotaExceeded(totalSize, quota);
+ }
} catch (Exception e) {
Slog.w(TAG, "Exception preflighting " + pkg.packageName + ": " + e.getMessage());
result = BackupTransport.AGENT_ERROR;
@@ -4550,6 +4604,7 @@ public class BackupManagerService {
final PackageInfo mTarget;
final FullBackupPreflight mPreflight;
final CountDownLatch mLatch;
+ private FullBackupEngine mEngine;
SinglePackageBackupRunner(ParcelFileDescriptor output, PackageInfo target,
IBackupTransport transport, CountDownLatch latch) throws IOException {
@@ -4563,9 +4618,9 @@ public class BackupManagerService {
public void run() {
try {
FileOutputStream out = new FileOutputStream(mOutput.getFileDescriptor());
- FullBackupEngine engine = new FullBackupEngine(out, mTarget.packageName,
+ mEngine = new FullBackupEngine(out, mTarget.packageName,
mPreflight, false);
- engine.backupOnePackage(mTarget);
+ mEngine.backupOnePackage(mTarget);
} catch (Exception e) {
Slog.e(TAG, "Exception during full package backup of " + mTarget);
} finally {
@@ -4578,6 +4633,10 @@ public class BackupManagerService {
}
}
+ public void sendQuotaExceeded(final long backupDataBytes, final long quotaBytes) {
+ mEngine.sendQuotaExceeded(backupDataBytes, quotaBytes);
+ }
+
long expectedSize() {
return mPreflight.expectedSize();
}
diff --git a/services/core/java/com/android/server/EventLogTags.logtags b/services/core/java/com/android/server/EventLogTags.logtags
index 7bf1deaf589c1..c59ecec725cd9 100644
--- a/services/core/java/com/android/server/EventLogTags.logtags
+++ b/services/core/java/com/android/server/EventLogTags.logtags
@@ -108,6 +108,7 @@ option java_package com.android.server
2826 backup_reset (Transport|3)
2827 backup_initialize
2828 backup_requested (Total|1|1),(Key-Value|1|1),(Full|1|1)
+2829 backup_quota_exceeded (Package|3)
2830 restore_start (Transport|3),(Source|2|5)
2831 restore_transport_failure
2832 restore_agent_failure (Package|3),(Message|3)
@@ -119,6 +120,7 @@ option java_package com.android.server
2842 full_backup_transport_failure
2843 full_backup_success (Package|3)
2844 full_restore_package (Package|3)
+2845 full_backup_quota_exceeded (Package|3)
2850 backup_transport_lifecycle (Transport|3),(Bound|1|1)