DO NOT MERGE Redact Account info from getCurrentSyncs am: a5cafd2a93
am: 06ef7dfdf0
* commit '06ef7dfdf0a3efb44326228c55309ec6df134376':
DO NOT MERGE Redact Account info from getCurrentSyncs
This commit is contained in:
@@ -25,6 +25,13 @@ import android.os.Parcelable.Creator;
|
|||||||
* Information about the sync operation that is currently underway.
|
* Information about the sync operation that is currently underway.
|
||||||
*/
|
*/
|
||||||
public class SyncInfo implements Parcelable {
|
public class SyncInfo implements Parcelable {
|
||||||
|
/**
|
||||||
|
* Used when the caller receiving this object doesn't have permission to access the accounts
|
||||||
|
* on device.
|
||||||
|
* @See Manifest.permission.GET_ACCOUNTS
|
||||||
|
*/
|
||||||
|
private static final Account REDACTED_ACCOUNT = new Account("*****", "*****");
|
||||||
|
|
||||||
/** @hide */
|
/** @hide */
|
||||||
public final int authorityId;
|
public final int authorityId;
|
||||||
|
|
||||||
@@ -45,6 +52,17 @@ public class SyncInfo implements Parcelable {
|
|||||||
*/
|
*/
|
||||||
public final long startTime;
|
public final long startTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a SyncInfo object with an unusable Account. Used when the caller receiving this
|
||||||
|
* object doesn't have access to the accounts on the device.
|
||||||
|
* @See Manifest.permission.GET_ACCOUNTS
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public static SyncInfo createAccountRedacted(
|
||||||
|
int authorityId, String authority, long startTime) {
|
||||||
|
return new SyncInfo(authorityId, REDACTED_ACCOUNT, authority, startTime);
|
||||||
|
}
|
||||||
|
|
||||||
/** @hide */
|
/** @hide */
|
||||||
public SyncInfo(int authorityId, Account account, String authority,
|
public SyncInfo(int authorityId, Account account, String authority,
|
||||||
long startTime) {
|
long startTime) {
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import android.content.SyncAdapterType;
|
|||||||
import android.content.SyncInfo;
|
import android.content.SyncInfo;
|
||||||
import android.content.SyncRequest;
|
import android.content.SyncRequest;
|
||||||
import android.content.SyncStatusInfo;
|
import android.content.SyncStatusInfo;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
import android.database.IContentObserver;
|
import android.database.IContentObserver;
|
||||||
import android.database.sqlite.SQLiteException;
|
import android.database.sqlite.SQLiteException;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
@@ -654,13 +655,26 @@ public final class ContentService extends IContentService.Stub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public List<SyncInfo> getCurrentSyncs() {
|
public List<SyncInfo> getCurrentSyncs() {
|
||||||
|
return getCurrentSyncsAsUser(UserHandle.getCallingUserId());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the user id supplied is different to the calling user, the caller must hold the
|
||||||
|
* INTERACT_ACROSS_USERS_FULL permission.
|
||||||
|
*/
|
||||||
|
public List<SyncInfo> getCurrentSyncsAsUser(int userId) {
|
||||||
|
enforceCrossUserPermission(userId,
|
||||||
|
"no permission to read the sync settings for user " + userId);
|
||||||
mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_STATS,
|
mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_STATS,
|
||||||
"no permission to read the sync stats");
|
"no permission to read the sync stats");
|
||||||
|
|
||||||
int userId = UserHandle.getCallingUserId();
|
final boolean canAccessAccounts =
|
||||||
|
mContext.checkCallingOrSelfPermission(Manifest.permission.GET_ACCOUNTS)
|
||||||
|
== PackageManager.PERMISSION_GRANTED;
|
||||||
long identityToken = clearCallingIdentity();
|
long identityToken = clearCallingIdentity();
|
||||||
try {
|
try {
|
||||||
return getSyncManager().getSyncStorageEngine().getCurrentSyncsCopy(userId);
|
return getSyncManager().getSyncStorageEngine()
|
||||||
|
.getCurrentSyncsCopy(userId, canAccessAccounts);
|
||||||
} finally {
|
} finally {
|
||||||
restoreCallingIdentity(identityToken);
|
restoreCallingIdentity(identityToken);
|
||||||
}
|
}
|
||||||
@@ -734,6 +748,21 @@ public final class ContentService extends IContentService.Stub {
|
|||||||
return service;
|
return service;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS_FULL
|
||||||
|
* permission, if the userHandle is not for the caller.
|
||||||
|
*
|
||||||
|
* @param userHandle the user handle of the user we want to act on behalf of.
|
||||||
|
* @param message the message to log on security exception.
|
||||||
|
*/
|
||||||
|
private void enforceCrossUserPermission(int userHandle, String message) {
|
||||||
|
final int callingUser = UserHandle.getCallingUserId();
|
||||||
|
if (callingUser != userHandle) {
|
||||||
|
mContext.enforceCallingOrSelfPermission(
|
||||||
|
Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hide this class since it is not part of api,
|
* Hide this class since it is not part of api,
|
||||||
* but current unittest framework requires it to be public
|
* but current unittest framework requires it to be public
|
||||||
|
|||||||
@@ -1306,15 +1306,23 @@ public class SyncStorageEngine extends Handler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return a copy of the current syncs data structure. Will not return
|
* @param userId Id of user to return current sync info.
|
||||||
* null.
|
* @param canAccessAccounts Determines whether to redact Account information from the result.
|
||||||
|
* @return a copy of the current syncs data structure. Will not return null.
|
||||||
*/
|
*/
|
||||||
public List<SyncInfo> getCurrentSyncsCopy(int userId) {
|
public List<SyncInfo> getCurrentSyncsCopy(int userId, boolean canAccessAccounts) {
|
||||||
synchronized (mAuthorities) {
|
synchronized (mAuthorities) {
|
||||||
final List<SyncInfo> syncs = getCurrentSyncsLocked(userId);
|
final List<SyncInfo> syncs = getCurrentSyncsLocked(userId);
|
||||||
final List<SyncInfo> syncsCopy = new ArrayList<SyncInfo>();
|
final List<SyncInfo> syncsCopy = new ArrayList<SyncInfo>();
|
||||||
for (SyncInfo sync : syncs) {
|
for (SyncInfo sync : syncs) {
|
||||||
syncsCopy.add(new SyncInfo(sync));
|
SyncInfo copy;
|
||||||
|
if (!canAccessAccounts) {
|
||||||
|
copy = SyncInfo.createAccountRedacted(
|
||||||
|
sync.authorityId, sync.authority, sync.startTime);
|
||||||
|
} else {
|
||||||
|
copy = new SyncInfo(sync);
|
||||||
|
}
|
||||||
|
syncsCopy.add(copy);
|
||||||
}
|
}
|
||||||
return syncsCopy;
|
return syncsCopy;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user