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:
@@ -217,8 +217,7 @@ public final class Bmgr {
|
|||||||
|
|
||||||
// The rest of the 'list' options work with a restore session on the current transport
|
// The rest of the 'list' options work with a restore session on the current transport
|
||||||
try {
|
try {
|
||||||
String curTransport = mBmgr.getCurrentTransport();
|
mRestore = mBmgr.beginRestoreSession(null, null);
|
||||||
mRestore = mBmgr.beginRestoreSession(curTransport);
|
|
||||||
if (mRestore == null) {
|
if (mRestore == null) {
|
||||||
System.err.println(BMGR_NOT_RUNNING_ERR);
|
System.err.println(BMGR_NOT_RUNNING_ERR);
|
||||||
return;
|
return;
|
||||||
@@ -349,8 +348,7 @@ public final class Bmgr {
|
|||||||
|
|
||||||
private void doRestorePackage(String pkg) {
|
private void doRestorePackage(String pkg) {
|
||||||
try {
|
try {
|
||||||
String curTransport = mBmgr.getCurrentTransport();
|
mRestore = mBmgr.beginRestoreSession(pkg, null);
|
||||||
mRestore = mBmgr.beginRestoreSession(curTransport);
|
|
||||||
if (mRestore == null) {
|
if (mRestore == null) {
|
||||||
System.err.println(BMGR_NOT_RUNNING_ERR);
|
System.err.println(BMGR_NOT_RUNNING_ERR);
|
||||||
return;
|
return;
|
||||||
@@ -378,8 +376,7 @@ public final class Bmgr {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
boolean didRestore = false;
|
boolean didRestore = false;
|
||||||
String curTransport = mBmgr.getCurrentTransport();
|
mRestore = mBmgr.beginRestoreSession(null, null);
|
||||||
mRestore = mBmgr.beginRestoreSession(curTransport);
|
|
||||||
if (mRestore == null) {
|
if (mRestore == null) {
|
||||||
System.err.println(BMGR_NOT_RUNNING_ERR);
|
System.err.println(BMGR_NOT_RUNNING_ERR);
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -138,8 +138,8 @@ public class BackupManager {
|
|||||||
if (sService != null) {
|
if (sService != null) {
|
||||||
RestoreSession session = null;
|
RestoreSession session = null;
|
||||||
try {
|
try {
|
||||||
String transport = sService.getCurrentTransport();
|
IRestoreSession binder = sService.beginRestoreSession(mContext.getPackageName(),
|
||||||
IRestoreSession binder = sService.beginRestoreSession(transport);
|
null);
|
||||||
session = new RestoreSession(mContext, binder);
|
session = new RestoreSession(mContext, binder);
|
||||||
result = session.restorePackage(mContext.getPackageName(), observer);
|
result = session.restorePackage(mContext.getPackageName(), observer);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
@@ -163,8 +163,8 @@ public class BackupManager {
|
|||||||
checkServiceBinder();
|
checkServiceBinder();
|
||||||
if (sService != null) {
|
if (sService != null) {
|
||||||
try {
|
try {
|
||||||
String transport = sService.getCurrentTransport();
|
// All packages, current transport
|
||||||
IRestoreSession binder = sService.beginRestoreSession(transport);
|
IRestoreSession binder = sService.beginRestoreSession(null, null);
|
||||||
session = new RestoreSession(mContext, binder);
|
session = new RestoreSession(mContext, binder);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Log.w(TAG, "beginRestoreSession() couldn't connect");
|
Log.w(TAG, "beginRestoreSession() couldn't connect");
|
||||||
|
|||||||
@@ -144,13 +144,25 @@ interface IBackupManager {
|
|||||||
String selectBackupTransport(String transport);
|
String selectBackupTransport(String transport);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Begin a restore session with the given transport (which may differ from the
|
* Begin a restore session. Either or both of packageName and transportID
|
||||||
* currently-active backup transport).
|
* 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.
|
* @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
|
* Notify the backup manager that a BackupAgent has completed the operation
|
||||||
|
|||||||
@@ -2398,15 +2398,45 @@ class BackupManagerService extends IBackupManager.Stub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Hand off a restore session
|
// Hand off a restore session
|
||||||
public IRestoreSession beginRestoreSession(String transport) {
|
public IRestoreSession beginRestoreSession(String packageName, String transport) {
|
||||||
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP, "beginRestoreSession");
|
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) {
|
synchronized(this) {
|
||||||
if (mActiveRestoreSession != null) {
|
if (mActiveRestoreSession != null) {
|
||||||
Slog.d(TAG, "Restore session requested but one already active");
|
Slog.d(TAG, "Restore session requested but one already active");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
mActiveRestoreSession = new ActiveRestoreSession(transport);
|
mActiveRestoreSession = new ActiveRestoreSession(packageName, transport);
|
||||||
}
|
}
|
||||||
return mActiveRestoreSession;
|
return mActiveRestoreSession;
|
||||||
}
|
}
|
||||||
@@ -2426,10 +2456,12 @@ class BackupManagerService extends IBackupManager.Stub {
|
|||||||
class ActiveRestoreSession extends IRestoreSession.Stub {
|
class ActiveRestoreSession extends IRestoreSession.Stub {
|
||||||
private static final String TAG = "RestoreSession";
|
private static final String TAG = "RestoreSession";
|
||||||
|
|
||||||
|
private String mPackageName;
|
||||||
private IBackupTransport mRestoreTransport = null;
|
private IBackupTransport mRestoreTransport = null;
|
||||||
RestoreSet[] mRestoreSets = null;
|
RestoreSet[] mRestoreSets = null;
|
||||||
|
|
||||||
ActiveRestoreSession(String transport) {
|
ActiveRestoreSession(String packageName, String transport) {
|
||||||
|
mPackageName = packageName;
|
||||||
mRestoreTransport = getTransport(transport);
|
mRestoreTransport = getTransport(transport);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2465,11 +2497,16 @@ class BackupManagerService extends IBackupManager.Stub {
|
|||||||
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
|
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
|
||||||
"performRestore");
|
"performRestore");
|
||||||
|
|
||||||
if (DEBUG) Slog.d(TAG, "performRestore token=" + Long.toHexString(token)
|
if (DEBUG) Slog.d(TAG, "restoreAll token=" + Long.toHexString(token)
|
||||||
+ " observer=" + observer);
|
+ " observer=" + observer);
|
||||||
|
|
||||||
if (mRestoreTransport == null || mRestoreSets == null) {
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2494,6 +2531,14 @@ class BackupManagerService extends IBackupManager.Stub {
|
|||||||
public synchronized int restorePackage(String packageName, IRestoreObserver observer) {
|
public synchronized int restorePackage(String packageName, IRestoreObserver observer) {
|
||||||
if (DEBUG) Slog.v(TAG, "restorePackage pkg=" + packageName + " obs=" + 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;
|
PackageInfo app = null;
|
||||||
try {
|
try {
|
||||||
app = mPackageManager.getPackageInfo(packageName, 0);
|
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
|
// the app has never been backed up from this device -- there's nothing
|
||||||
// to do but return failure.
|
// to do but return failure.
|
||||||
if (token == 0) {
|
if (token == 0) {
|
||||||
|
if (DEBUG) Slog.w(TAG, "No data available for this package; not restoring");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2542,9 +2588,6 @@ class BackupManagerService extends IBackupManager.Stub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void endRestoreSession() {
|
public synchronized void endRestoreSession() {
|
||||||
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
|
|
||||||
"endRestoreSession");
|
|
||||||
|
|
||||||
if (DEBUG) Slog.d(TAG, "endRestoreSession");
|
if (DEBUG) Slog.d(TAG, "endRestoreSession");
|
||||||
|
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
|
|||||||
Reference in New Issue
Block a user