diff options
Diffstat (limited to 'services/java/com/android/server/BackupManagerService.java')
-rw-r--r-- | services/java/com/android/server/BackupManagerService.java | 61 |
1 files changed, 52 insertions, 9 deletions
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java index 6a86076..bebd013 100644 --- a/services/java/com/android/server/BackupManagerService.java +++ b/services/java/com/android/server/BackupManagerService.java @@ -2399,15 +2399,45 @@ class BackupManagerService extends IBackupManager.Stub { } // Hand off a restore session - public IRestoreSession beginRestoreSession(String transport) { - mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP, "beginRestoreSession"); + public IRestoreSession beginRestoreSession(String packageName, String transport) { + if (DEBUG) Slog.v(TAG, "beginRestoreSession: pkg=" + packageName + + " transport=" + transport); + + boolean needPermission = true; + if (transport == null) { + transport = mCurrentTransport; + + if (packageName != null) { + PackageInfo app = null; + try { + app = mPackageManager.getPackageInfo(packageName, 0); + } catch (NameNotFoundException nnf) { + Slog.w(TAG, "Asked to restore nonexistent pkg " + packageName); + throw new IllegalArgumentException("Package " + packageName + " not found"); + } + + if (app.applicationInfo.uid == Binder.getCallingUid()) { + // So: using the current active transport, and the caller has asked + // that its own package will be restored. In this narrow use case + // we do not require the caller to hold the permission. + needPermission = false; + } + } + } + + if (needPermission) { + mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP, + "beginRestoreSession"); + } else { + if (DEBUG) Slog.d(TAG, "restoring self on current transport; no permission needed"); + } synchronized(this) { if (mActiveRestoreSession != null) { Slog.d(TAG, "Restore session requested but one already active"); return null; } - mActiveRestoreSession = new ActiveRestoreSession(transport); + mActiveRestoreSession = new ActiveRestoreSession(packageName, transport); } return mActiveRestoreSession; } @@ -2427,10 +2457,12 @@ class BackupManagerService extends IBackupManager.Stub { class ActiveRestoreSession extends IRestoreSession.Stub { private static final String TAG = "RestoreSession"; + private String mPackageName; private IBackupTransport mRestoreTransport = null; RestoreSet[] mRestoreSets = null; - ActiveRestoreSession(String transport) { + ActiveRestoreSession(String packageName, String transport) { + mPackageName = packageName; mRestoreTransport = getTransport(transport); } @@ -2466,11 +2498,16 @@ class BackupManagerService extends IBackupManager.Stub { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP, "performRestore"); - if (DEBUG) Slog.d(TAG, "performRestore token=" + Long.toHexString(token) + if (DEBUG) Slog.d(TAG, "restoreAll token=" + Long.toHexString(token) + " observer=" + observer); if (mRestoreTransport == null || mRestoreSets == null) { - Slog.e(TAG, "Ignoring performRestore() with no restore set"); + Slog.e(TAG, "Ignoring restoreAll() with no restore set"); + return -1; + } + + if (mPackageName != null) { + Slog.e(TAG, "Ignoring restoreAll() on single-package session"); return -1; } @@ -2495,6 +2532,14 @@ class BackupManagerService extends IBackupManager.Stub { public synchronized int restorePackage(String packageName, IRestoreObserver observer) { if (DEBUG) Slog.v(TAG, "restorePackage pkg=" + packageName + " obs=" + observer); + if (mPackageName != null) { + if (! mPackageName.equals(packageName)) { + Slog.e(TAG, "Ignoring attempt to restore pkg=" + packageName + + " on session for package " + mPackageName); + return -1; + } + } + PackageInfo app = null; try { app = mPackageManager.getPackageInfo(packageName, 0); @@ -2529,6 +2574,7 @@ class BackupManagerService extends IBackupManager.Stub { // the app has never been backed up from this device -- there's nothing // to do but return failure. if (token == 0) { + if (DEBUG) Slog.w(TAG, "No data available for this package; not restoring"); return -1; } @@ -2543,9 +2589,6 @@ class BackupManagerService extends IBackupManager.Stub { } public synchronized void endRestoreSession() { - mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP, - "endRestoreSession"); - if (DEBUG) Slog.d(TAG, "endRestoreSession"); synchronized (this) { |