summaryrefslogtreecommitdiffstats
path: root/services/java/com/android/server/BackupManagerService.java
diff options
context:
space:
mode:
Diffstat (limited to 'services/java/com/android/server/BackupManagerService.java')
-rw-r--r--services/java/com/android/server/BackupManagerService.java61
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) {