From 872d3b6e19933af6fa9ae65214b9f6df04fc3222 Mon Sep 17 00:00:00 2001 From: Sergey Poromov Date: Tue, 12 Jan 2016 15:48:08 +0100 Subject: [PATCH] Quota exceeded API in BackupAgent Should be also implemented in GMS BackupTransport. Bug: 25693504 Change-Id: I6e4b2edb6d62addca0aced3e801d7629fb9394ca --- api/current.txt | 1 + api/system-current.txt | 4 + api/test-current.txt | 1 + core/java/android/app/IBackupAgent.aidl | 21 +++++ core/java/android/app/backup/BackupAgent.java | 37 ++++++++ .../android/app/backup/BackupManager.java | 10 +++ .../android/app/backup/BackupTransport.java | 18 ++++ .../internal/backup/IBackupTransport.aidl | 10 +++ .../internal/backup/LocalTransport.java | 21 ++++- .../server/backup/BackupManagerService.java | 89 +++++++++++++++---- .../com/android/server/EventLogTags.logtags | 2 + 11 files changed, 198 insertions(+), 16 deletions(-) diff --git a/api/current.txt b/api/current.txt index 9de0af6376a0c..44d5994c65c37 100644 --- a/api/current.txt +++ b/api/current.txt @@ -6096,6 +6096,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 e723d0993b371..1602fa2232e87 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -6244,6 +6244,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(); @@ -6306,6 +6307,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 } @@ -6338,6 +6340,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); @@ -6363,6 +6366,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 e39efca55ab66..fb384f83c6dd2 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -6098,6 +6098,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 d63dd0c8d03ab..be517c3ab6719 100644 --- a/services/backup/java/com/android/server/backup/BackupManagerService.java +++ b/services/backup/java/com/android/server/backup/BackupManagerService.java @@ -3155,8 +3155,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, @@ -3201,6 +3202,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); @@ -3221,6 +3226,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. @@ -3463,6 +3482,7 @@ public class BackupManagerService { OutputStream mOutput; FullBackupPreflight mPreflightHook; IFullBackupRestoreObserver mObserver; + IBackupAgent mAgent; File mFilesDir; File mManifestFile; File mMetadataFile; @@ -3549,14 +3569,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); } @@ -3579,7 +3599,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; @@ -3627,6 +3647,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 @@ -4321,6 +4351,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. @@ -4364,6 +4403,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 @@ -4371,35 +4412,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); @@ -4480,6 +4526,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; @@ -4527,6 +4581,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 { @@ -4540,9 +4595,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 { @@ -4555,6 +4610,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)