diff options
Diffstat (limited to 'core/java/android/accounts')
3 files changed, 74 insertions, 81 deletions
diff --git a/core/java/android/accounts/AccountAuthenticatorCache.java b/core/java/android/accounts/AccountAuthenticatorCache.java index 7214c50..f937cde 100644 --- a/core/java/android/accounts/AccountAuthenticatorCache.java +++ b/core/java/android/accounts/AccountAuthenticatorCache.java @@ -16,17 +16,18 @@ package android.accounts; +import android.content.Context; import android.content.pm.PackageManager; import android.content.pm.RegisteredServicesCache; import android.content.pm.XmlSerializerAndParser; import android.content.res.Resources; import android.content.res.TypedArray; -import android.content.Context; -import android.util.AttributeSet; import android.text.TextUtils; +import android.util.AttributeSet; + import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlSerializer; import org.xmlpull.v1.XmlPullParserException; +import org.xmlpull.v1.XmlSerializer; import java.io.IOException; diff --git a/core/java/android/accounts/AccountManagerService.java b/core/java/android/accounts/AccountManagerService.java index fc569e0..cc90b86 100644 --- a/core/java/android/accounts/AccountManagerService.java +++ b/core/java/android/accounts/AccountManagerService.java @@ -18,7 +18,7 @@ package android.accounts; import android.Manifest; import android.app.ActivityManager; -import android.app.AppGlobals; +import android.app.ActivityManagerNative; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; @@ -32,10 +32,9 @@ import android.content.ServiceConnection; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; +import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.RegisteredServicesCache; import android.content.pm.RegisteredServicesCacheListener; -import android.content.pm.UserInfo; -import android.content.res.Resources; import android.database.Cursor; import android.database.DatabaseUtils; import android.database.sqlite.SQLiteDatabase; @@ -59,6 +58,8 @@ import android.util.SparseArray; import com.android.internal.R; import com.android.internal.util.IndentingPrintWriter; +import com.google.android.collect.Lists; +import com.google.android.collect.Sets; import java.io.File; import java.io.FileDescriptor; @@ -67,8 +68,8 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashMap; +import java.util.HashSet; import java.util.LinkedHashMap; -import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; @@ -243,8 +244,7 @@ public class AccountManagerService } public void systemReady() { - mAuthenticatorCache.generateServicesMap(); - initUser(0); + initUser(UserHandle.USER_OWNER); } private UserManager getUserManager() { @@ -300,6 +300,14 @@ public class AccountManagerService } private void validateAccountsAndPopulateCache(UserAccounts accounts) { + mAuthenticatorCache.invalidateCache(accounts.userId); + + final HashSet<AuthenticatorDescription> knownAuth = Sets.newHashSet(); + for (RegisteredServicesCache.ServiceInfo<AuthenticatorDescription> service : + mAuthenticatorCache.getAllServices(accounts.userId)) { + knownAuth.add(service.type); + } + synchronized (accounts.cacheLock) { final SQLiteDatabase db = accounts.openHelper.getWritableDatabase(); boolean accountDeleted = false; @@ -314,8 +322,8 @@ public class AccountManagerService final long accountId = cursor.getLong(0); final String accountType = cursor.getString(1); final String accountName = cursor.getString(2); - if (mAuthenticatorCache.getServiceInfo( - AuthenticatorDescription.newKey(accountType)) == null) { + + if (!knownAuth.contains(AuthenticatorDescription.newKey(accountType))) { Log.d(TAG, "deleting account " + accountName + " because type " + accountType + " no longer has a registered authenticator"); db.delete(TABLE_ACCOUNTS, ACCOUNTS_ID + "=" + accountId, null); @@ -390,20 +398,9 @@ public class AccountManagerService } } - private List<UserInfo> getAllUsers() { - return getUserManager().getUsers(); - } - - public void onServiceChanged(AuthenticatorDescription desc, boolean removed) { - // Validate accounts for all users - List<UserInfo> users = getAllUsers(); - if (users == null) { - validateAccountsAndPopulateCache(getUserAccountsForCaller()); - } else { - for (UserInfo user : users) { - validateAccountsAndPopulateCache(getUserAccounts(user.id)); - } - } + @Override + public void onServiceChanged(AuthenticatorDescription desc, int userId, boolean removed) { + validateAccountsAndPopulateCache(getUserAccounts(userId)); } public String getPassword(Account account) { @@ -470,10 +467,11 @@ public class AccountManagerService + "caller's uid " + Binder.getCallingUid() + ", pid " + Binder.getCallingPid()); } - long identityToken = clearCallingIdentity(); + final int userId = UserHandle.getCallingUserId(); + final long identityToken = clearCallingIdentity(); try { Collection<AccountAuthenticatorCache.ServiceInfo<AuthenticatorDescription>> - authenticatorCollection = mAuthenticatorCache.getAllServices(); + authenticatorCollection = mAuthenticatorCache.getAllServices(userId); AuthenticatorDescription[] types = new AuthenticatorDescription[authenticatorCollection.size()]; int i = 0; @@ -1055,9 +1053,9 @@ public class AccountManagerService if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null"); checkBinderPermission(Manifest.permission.USE_CREDENTIALS); final UserAccounts accounts = getUserAccountsForCaller(); - AccountAuthenticatorCache.ServiceInfo<AuthenticatorDescription> authenticatorInfo = - mAuthenticatorCache.getServiceInfo( - AuthenticatorDescription.newKey(account.type)); + final RegisteredServicesCache.ServiceInfo<AuthenticatorDescription> authenticatorInfo; + authenticatorInfo = mAuthenticatorCache.getServiceInfo( + AuthenticatorDescription.newKey(account.type), accounts.userId); final boolean customTokens = authenticatorInfo != null && authenticatorInfo.type.customTokens; @@ -1074,7 +1072,7 @@ public class AccountManagerService if (notifyOnAuthFailure) { loginOptions.putBoolean(AccountManager.KEY_NOTIFY_ON_FAILURE, true); } - + long identityToken = clearCallingIdentity(); try { // if the caller has permission, do the peek. otherwise go the more expensive @@ -1183,28 +1181,6 @@ public class AccountManagerService account, authTokenType, uid), n, user); } - String getAccountLabel(String accountType) { - RegisteredServicesCache.ServiceInfo<AuthenticatorDescription> serviceInfo = - mAuthenticatorCache.getServiceInfo( - AuthenticatorDescription.newKey(accountType)); - if (serviceInfo == null) { - throw new IllegalArgumentException("unknown account type: " + accountType); - } - - final Context authContext; - try { - authContext = mContext.createPackageContext( - serviceInfo.type.packageName, 0); - } catch (PackageManager.NameNotFoundException e) { - throw new IllegalArgumentException("unknown account type: " + accountType); - } - try { - return authContext.getString(serviceInfo.type.labelId); - } catch (Resources.NotFoundException e) { - throw new IllegalArgumentException("unknown account type: " + accountType); - } - } - private Intent newGrantCredentialsPermissionIntent(Account account, int uid, AccountAuthenticatorResponse response, String authTokenType, String authTokenLabel) { @@ -1506,28 +1482,35 @@ public class AccountManagerService } /** - * Returns all the accounts qualified by user. + * Returns accounts for all running users. + * * @hide */ - public AccountAndUser[] getAllAccounts() { - ArrayList<AccountAndUser> allAccounts = new ArrayList<AccountAndUser>(); - List<UserInfo> users = getAllUsers(); - if (users == null) return new AccountAndUser[0]; - - synchronized(mUsers) { - for (UserInfo user : users) { - UserAccounts userAccounts = getUserAccounts(user.id); + public AccountAndUser[] getRunningAccounts() { + final int[] runningUserIds; + try { + runningUserIds = ActivityManagerNative.getDefault().getRunningUserIds(); + } catch (RemoteException e) { + // Running in system_server; should never happen + throw new RuntimeException(e); + } + + final ArrayList<AccountAndUser> runningAccounts = Lists.newArrayList(); + synchronized (mUsers) { + for (int userId : runningUserIds) { + UserAccounts userAccounts = getUserAccounts(userId); if (userAccounts == null) continue; synchronized (userAccounts.cacheLock) { Account[] accounts = getAccountsFromCacheLocked(userAccounts, null); for (int a = 0; a < accounts.length; a++) { - allAccounts.add(new AccountAndUser(accounts[a], user.id)); + runningAccounts.add(new AccountAndUser(accounts[a], userId)); } } } } - AccountAndUser[] accountsArray = new AccountAndUser[allAccounts.size()]; - return allAccounts.toArray(accountsArray); + + AccountAndUser[] accountsArray = new AccountAndUser[runningAccounts.size()]; + return runningAccounts.toArray(accountsArray); } public Account[] getAccounts(String type) { @@ -1836,9 +1819,9 @@ public class AccountManagerService * if no authenticator or the bind fails then return false, otherwise return true */ private boolean bindToAuthenticator(String authenticatorType) { - AccountAuthenticatorCache.ServiceInfo<AuthenticatorDescription> authenticatorInfo = - mAuthenticatorCache.getServiceInfo( - AuthenticatorDescription.newKey(authenticatorType)); + final AccountAuthenticatorCache.ServiceInfo<AuthenticatorDescription> authenticatorInfo; + authenticatorInfo = mAuthenticatorCache.getServiceInfo( + AuthenticatorDescription.newKey(authenticatorType), mAccounts.userId); if (authenticatorInfo == null) { if (Log.isLoggable(TAG, Log.VERBOSE)) { Log.v(TAG, "there is no authenticator for " + authenticatorType @@ -2083,7 +2066,7 @@ public class AccountManagerService } fout.println(); - mAuthenticatorCache.dump(fd, fout, args); + mAuthenticatorCache.dump(fd, fout, args, userAccounts.userId); } } } @@ -2154,11 +2137,21 @@ public class AccountManagerService throw new SecurityException(msg); } - private boolean inSystemImage(int callerUid) { - String[] packages = mPackageManager.getPackagesForUid(callerUid); + private boolean inSystemImage(int callingUid) { + final int callingUserId = UserHandle.getUserId(callingUid); + + final PackageManager userPackageManager; + try { + userPackageManager = mContext.createPackageContextAsUser( + "android", 0, new UserHandle(callingUserId)).getPackageManager(); + } catch (NameNotFoundException e) { + return false; + } + + String[] packages = userPackageManager.getPackagesForUid(callingUid); for (String name : packages) { try { - PackageInfo packageInfo = mPackageManager.getPackageInfo(name, 0 /* flags */); + PackageInfo packageInfo = userPackageManager.getPackageInfo(name, 0 /* flags */); if (packageInfo != null && (packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { return true; @@ -2186,8 +2179,9 @@ public class AccountManagerService } private boolean hasAuthenticatorUid(String accountType, int callingUid) { + final int callingUserId = UserHandle.getUserId(callingUid); for (RegisteredServicesCache.ServiceInfo<AuthenticatorDescription> serviceInfo : - mAuthenticatorCache.getAllServices()) { + mAuthenticatorCache.getAllServices(callingUserId)) { if (serviceInfo.type.type.equals(accountType)) { return (serviceInfo.uid == callingUid) || (mPackageManager.checkSignatures(serviceInfo.uid, callingUid) diff --git a/core/java/android/accounts/IAccountAuthenticatorCache.java b/core/java/android/accounts/IAccountAuthenticatorCache.java index 20dd585..06c2106 100644 --- a/core/java/android/accounts/IAccountAuthenticatorCache.java +++ b/core/java/android/accounts/IAccountAuthenticatorCache.java @@ -39,18 +39,19 @@ public interface IAccountAuthenticatorCache { * matches the account type or null if none is present */ RegisteredServicesCache.ServiceInfo<AuthenticatorDescription> getServiceInfo( - AuthenticatorDescription type); + AuthenticatorDescription type, int userId); /** * @return A copy of a Collection of all the current Authenticators. */ - Collection<RegisteredServicesCache.ServiceInfo<AuthenticatorDescription>> getAllServices(); + Collection<RegisteredServicesCache.ServiceInfo<AuthenticatorDescription>> getAllServices( + int userId); /** * Dumps the state of the cache. See * {@link android.os.Binder#dump(java.io.FileDescriptor, java.io.PrintWriter, String[])} */ - void dump(FileDescriptor fd, PrintWriter fout, String[] args); + void dump(FileDescriptor fd, PrintWriter fout, String[] args, int userId); /** * Sets a listener that will be notified whenever the authenticator set changes @@ -61,8 +62,5 @@ public interface IAccountAuthenticatorCache { void setListener(RegisteredServicesCacheListener<AuthenticatorDescription> listener, Handler handler); - /** - * Refreshes the authenticator cache. - */ - void generateServicesMap(); -}
\ No newline at end of file + void invalidateCache(int userId); +} |