am 6ec91731: DO NOT MERGE : Permission fix: don\'t require BACKUP perm for self-restores

* commit '6ec91731cbf6ee1a9a914d341fab9567d1599018':
  DO NOT MERGE : Permission fix: don't require BACKUP perm for self-restores
This commit is contained in:
Chris Tate
2011-01-09 13:04:01 -08:00
committed by Android Git Automerger
4 changed files with 75 additions and 23 deletions

View File

@@ -217,8 +217,7 @@ public final class Bmgr {
// The rest of the 'list' options work with a restore session on the current transport
try {
String curTransport = mBmgr.getCurrentTransport();
mRestore = mBmgr.beginRestoreSession(curTransport);
mRestore = mBmgr.beginRestoreSession(null, null);
if (mRestore == null) {
System.err.println(BMGR_NOT_RUNNING_ERR);
return;
@@ -349,8 +348,7 @@ public final class Bmgr {
private void doRestorePackage(String pkg) {
try {
String curTransport = mBmgr.getCurrentTransport();
mRestore = mBmgr.beginRestoreSession(curTransport);
mRestore = mBmgr.beginRestoreSession(pkg, null);
if (mRestore == null) {
System.err.println(BMGR_NOT_RUNNING_ERR);
return;
@@ -378,8 +376,7 @@ public final class Bmgr {
try {
boolean didRestore = false;
String curTransport = mBmgr.getCurrentTransport();
mRestore = mBmgr.beginRestoreSession(curTransport);
mRestore = mBmgr.beginRestoreSession(null, null);
if (mRestore == null) {
System.err.println(BMGR_NOT_RUNNING_ERR);
return;

View File

@@ -138,8 +138,8 @@ public class BackupManager {
if (sService != null) {
RestoreSession session = null;
try {
String transport = sService.getCurrentTransport();
IRestoreSession binder = sService.beginRestoreSession(transport);
IRestoreSession binder = sService.beginRestoreSession(mContext.getPackageName(),
null);
session = new RestoreSession(mContext, binder);
result = session.restorePackage(mContext.getPackageName(), observer);
} catch (RemoteException e) {
@@ -163,8 +163,8 @@ public class BackupManager {
checkServiceBinder();
if (sService != null) {
try {
String transport = sService.getCurrentTransport();
IRestoreSession binder = sService.beginRestoreSession(transport);
// All packages, current transport
IRestoreSession binder = sService.beginRestoreSession(null, null);
session = new RestoreSession(mContext, binder);
} catch (RemoteException e) {
Log.w(TAG, "beginRestoreSession() couldn't connect");

View File

@@ -144,13 +144,25 @@ interface IBackupManager {
String selectBackupTransport(String transport);
/**
* Begin a restore session with the given transport (which may differ from the
* currently-active backup transport).
* Begin a restore session. Either or both of packageName and transportID
* may be null. If packageName is non-null, then only the given package will be
* considered for restore. If transportID is null, then the restore will use
* the current active transport.
* <p>
* This method requires the android.permission.BACKUP permission <i>except</i>
* when transportID is null and packageName is the name of the caller's own
* package. In that case, the restore session returned is suitable for supporting
* the BackupManager.requestRestore() functionality via RestoreSession.restorePackage()
* without requiring the app to hold any special permission.
*
* @param transport The name of the transport to use for the restore operation.
* @param packageName The name of the single package for which a restore will
* be requested. May be null, in which case all packages in the restore
* set can be restored.
* @param transportID The name of the transport to use for the restore operation.
* May be null, in which case the current active transport is used.
* @return An interface to the restore session, or null on error.
*/
IRestoreSession beginRestoreSession(String transportID);
IRestoreSession beginRestoreSession(String packageName, String transportID);
/**
* Notify the backup manager that a BackupAgent has completed the operation

View File

@@ -2398,15 +2398,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;
}
@@ -2426,10 +2456,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);
}
@@ -2465,11 +2497,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;
}
@@ -2494,6 +2531,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);
@@ -2528,6 +2573,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;
}
@@ -2542,9 +2588,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) {