Revert "Implement Account Discovery API."
This reverts commit 58fa836210a2872e58e8890456c2cd14a4b0fd3d.
Change-Id: Iffc9c5eb63db382b720b45ff5e8f1948db908a03
(cherry picked from commit 2e22cfbefb8848e52e29827c94225ed9409af4ad)
diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java
index 2be84c1..8185818 100644
--- a/core/java/android/accounts/AccountManager.java
+++ b/core/java/android/accounts/AccountManager.java
@@ -328,6 +328,7 @@
/**
* Token type for the special case where a UID has access only to an account
* but no authenticator specific auth token types.
+ *
* @hide
*/
public static final String ACCOUNT_ACCESS_TOKEN_TYPE =
@@ -353,9 +354,9 @@
* the applications are added, accounts are removed, or an account's credentials (saved
* password, etc) are changed. List of supported account types shoud be specified in the
* Manifest file using {@link #SUPPORTED_ACCOUNT_TYPES}
- * @hide
- * @see #addOnAccountsUpdatedListener
*
+ * @see #addOnAccountsUpdatedListener
+ * @hide
*/
public static final String ACTION_VISIBLE_ACCOUNTS_CHANGED =
"android.accounts.action.VISIBLE_ACCOUNTS_CHANGED";
@@ -363,7 +364,6 @@
/**
* Authenticators may subscribe to get notifications about apps interested in their managed account
* types using {@link #SUPPORTED_ACCOUNT_TYPES}.
- * Package name will be specified using {@link Intent.EXTRA_PACKAGE_NAME}
* @hide
*/
public static final String ACTION_ACCOUNTS_LISTENER_PACKAGE_INSTALLED =
@@ -1024,7 +1024,7 @@
public boolean isAccountVisible(Account account, int uid) {
try {
Integer visibility = mService.getAccountVisibility(account, uid);
- return visibility == VISIBILITY_USER_MANAGED_VISIBLE
+ return visibility == VISIBILITY_USER_MANAGED_NOT_VISIBLE
|| visibility == VISIBILITY_VISIBLE;
} catch (RemoteException re) {
throw re.rethrowFromSystemServer();
@@ -1058,7 +1058,6 @@
/**
* Gets visibility of certain account for given UID. Possible returned values are:
* <ul>
- * <li>{@link #VISIBILITY_UNDEFINED}</li>
* <li>{@link #VISIBILITY_VISIBLE}</li>
* <li>{@link #VISIBILITY_USER_MANAGED_VISIBLE}</li>
* <li>{@link #VISIBILITY_NOT_VISIBLE}
diff --git a/core/java/android/accounts/ChooseAccountActivity.java b/core/java/android/accounts/ChooseAccountActivity.java
index 16a45ba..242b3ea 100644
--- a/core/java/android/accounts/ChooseAccountActivity.java
+++ b/core/java/android/accounts/ChooseAccountActivity.java
@@ -52,9 +52,7 @@
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- // TODO This activity is only used by getAuthTokenByFeatures and can not see
- // VISIBILITY_USER_MANAGED_NOT_VISIBLE accounts. It should be moved to account managed
- // service.
+
mAccounts = getIntent().getParcelableArrayExtra(AccountManager.KEY_ACCOUNTS);
mAccountManagerResponse =
getIntent().getParcelableExtra(AccountManager.KEY_ACCOUNT_MANAGER_RESPONSE);
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 48805d8..a77a9cd 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -480,9 +480,6 @@
<protected-broadcast android:name="android.intent.action.ACTION_RADIO_OFF" />
<protected-broadcast android:name="android.accounts.LOGIN_ACCOUNTS_CHANGED" />
- <protected-broadcast android:name="android.accounts.action.VISIBLE_ACCOUNTS_CHANGED" />
- <protected-broadcast android:name="android.accounts.action.ACCOUNTS_LISTENER_PACKAGE_INSTALLED" />
-
<protected-broadcast android:name="com.android.sync.SYNC_CONN_STATUS_CHANGED" />
<protected-broadcast android:name="com.android.phone.SIP_INCOMING_CALL" />
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index 14c6529..11e1a9d 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -63,8 +63,8 @@
import android.content.pm.Signature;
import android.content.pm.UserInfo;
import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteStatement;
-import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
import android.os.Environment;
@@ -76,7 +76,6 @@
import android.os.Process;
import android.os.RemoteCallback;
import android.os.RemoteException;
-import android.os.StrictMode;
import android.os.SystemClock;
import android.os.UserHandle;
import android.os.UserManager;
@@ -112,16 +111,15 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
-import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
-import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
+import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicInteger;
@@ -176,18 +174,17 @@
private static final String PRE_N_DATABASE_NAME = "accounts.db";
private static final Intent ACCOUNTS_CHANGED_INTENT;
- private static final int SIGNATURE_CHECK_MISMATCH = 0;
- private static final int SIGNATURE_CHECK_MATCH = 1;
- private static final int SIGNATURE_CHECK_UID_MATCH = 2;
-
static {
ACCOUNTS_CHANGED_INTENT = new Intent(AccountManager.LOGIN_ACCOUNTS_CHANGED_ACTION);
ACCOUNTS_CHANGED_INTENT.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
}
+
private final LinkedHashMap<String, Session> mSessions = new LinkedHashMap<String, Session>();
private final AtomicInteger mNotificationIds = new AtomicInteger(1);
+ private static final String NEW_ACCOUNT_VISIBLE = "android.accounts.NEW_ACCOUNT_VISIBLE";
+
static class UserAccounts {
private final int userId;
final AccountsDb accountsDb;
@@ -207,10 +204,6 @@
/** protected by the {@link #cacheLock} */
private final TokenCache accountTokenCaches = new TokenCache();
- /** protected by the {@link #cacheLock} */
- private final Map<String, LinkedHashSet<String>>
- mApplicationAccountRequestMappings = new HashMap<>();
-
/**
* protected by the {@link #cacheLock}
*
@@ -292,26 +285,7 @@
@Override
public void run() {
purgeOldGrantsAll();
- int uidOfUninstalledApplication =
- intent.getIntExtra(Intent.EXTRA_UID, -1);
- /* remove visibility data for UID */
- if (uidOfUninstalledApplication != -1) {
- UserAccounts ua = getUserAccounts(UserHandle
- .getUserId(uidOfUninstalledApplication));
- // Stop sending notifications about accounts change to uninstalled
- // application.
- Uri intentData = intent.getData();
- String packageName = intentData != null
- ? intentData.getSchemeSpecificPart() : null;
- unregisterAccountTypesSupported(packageName, ua);
- String[] allPackages = mPackageManager
- .getPackagesForUid(uidOfUninstalledApplication);
- // Check that there are no other packages that share uid.
- if (allPackages == null) {
- deleteAccountVisibilityForUid(uidOfUninstalledApplication, ua);
- }
- }
-
+ // TODO remove visibility entries.
}
};
mHandler.post(purgingRunnable);
@@ -336,8 +310,7 @@
registerAccountTypesSupported(
uidOfInstalledApplication,
getUserAccounts(
- UserHandle.getUserId(uidOfInstalledApplication)),
- true /*notify*/);
+ UserHandle.getUserId(uidOfInstalledApplication)));
}
}
});
@@ -407,13 +380,11 @@
final long identity = Binder.clearCallingIdentity();
try {
for (String packageName : packageNames) {
- // if app asked for permission we need to cancel notification even
- // for O+ applications.
- if (mPackageManager.checkPermission(
- Manifest.permission.GET_ACCOUNTS,
- packageName) != PackageManager.PERMISSION_GRANTED) {
- continue;
- }
+ if (mPackageManager.checkPermission(
+ Manifest.permission.GET_ACCOUNTS, packageName)
+ != PackageManager.PERMISSION_GRANTED) {
+ continue;
+ }
if (accounts == null) {
accounts = getAccountsAsUser(null, userId, "android");
@@ -434,10 +405,6 @@
});
}
- private boolean deleteAccountVisibilityForUid(int uid, UserAccounts accounts) {
- return accounts.accountsDb.deleteAccountVisibilityForUid(uid);
- }
-
private void cancelAccountAccessRequestNotificationIfNeeded(int uid,
boolean checkAccess) {
Account[] accounts = getAccountsAsUser(null, UserHandle.getUserId(uid), "android");
@@ -476,95 +443,22 @@
}
@Override
- public boolean addAccountExplicitlyWithVisibility(Account account, String password,
- Bundle extras, Map uidToVisibility) {
- Bundle.setDefusable(extras, true);
-
- final int callingUid = Binder.getCallingUid();
- if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, "addAccountExplicitly: " + account + ", caller's uid " + callingUid
- + ", pid " + Binder.getCallingPid());
- }
- Preconditions.checkNotNull(account, "account cannot be null");
- int userId = UserHandle.getCallingUserId();
- if (!isAccountManagedByCaller(account.type, callingUid, userId)) {
- String msg = String.format("uid %s cannot explicitly add accounts of type: %s",
- callingUid, account.type);
- throw new SecurityException(msg);
- }
- /*
- * Child users are not allowed to add accounts. Only the accounts that are shared by the
- * parent profile can be added to child profile.
- *
- * TODO: Only allow accounts that were shared to be added by a limited user.
- */
- // fails if the account already exists
- long identityToken = clearCallingIdentity();
- try {
- UserAccounts accounts = getUserAccounts(userId);
- return addAccountInternal(accounts, account, password, extras, callingUid,
- (Map<Integer, Integer>) uidToVisibility);
- } finally {
- restoreCallingIdentity(identityToken);
- }
+ public boolean addAccountExplicitlyWithVisibility(Account account, String password, Bundle extras,
+ Map uidToVisibility) {
+ // TODO implementation
+ return false;
}
@Override
public Map<Account, Integer> getAccountsAndVisibilityForPackage(String packageName,
String accountType) {
- int callingUid = Binder.getCallingUid();
- List<String> managedTypes =
- getTypesManagedByCaller(callingUid, UserHandle.getUserId(callingUid));
- if ((accountType != null && !managedTypes.contains(accountType))
- || (accountType == null && !UserHandle.isSameApp(callingUid, Process.SYSTEM_UID))) {
- throw new SecurityException(
- "getAccountsAndVisibilityForPackage() called from unauthorized uid "
- + callingUid + " with packageName=" + packageName);
- }
- if (accountType != null) {
- managedTypes = new ArrayList<String>();
- managedTypes.add(accountType);
- }
-
- return getAccountsAndVisibilityForPackage(packageName, managedTypes, callingUid,
- getUserAccounts(UserHandle.getUserId(callingUid)));
+ // TODO Implement.
+ return new HashMap<Account, Integer>();
}
- /*
- * accountTypes may not be null
- */
- private Map<Account, Integer> getAccountsAndVisibilityForPackage(String packageName,
- List<String> accountTypes, Integer callingUid, UserAccounts accounts) {
- int uid = 0;
- try {
- uid = mPackageManager.getPackageUidAsUser(packageName,
- UserHandle.getUserId(callingUid));
- } catch (NameNotFoundException e) {
- Log.d("Package not found ", e.getMessage());
- return new HashMap<>();
- }
-
- Map<Account, Integer> result = new HashMap<>();
- for (String accountType : accountTypes) {
- synchronized (accounts.cacheLock) {
- final Account[] accountsOfType = accounts.accountCache.get(accountType);
- if (accountsOfType != null) {
- for (Account account : accountsOfType) {
- result.put(account,
- resolveAccountVisibility(account, uid, packageName, accounts));
- }
- }
- }
- }
- return filterSharedAccounts(accounts, result, callingUid, packageName);
- }
-
-
@Override
public int[] getRequestingUidsForType(String accountType) {
int callingUid = Binder.getCallingUid();
- UserAccounts accounts = getUserAccounts(
- UserHandle.getUserId(callingUid));
if (!isAccountManagedByCaller(accountType, callingUid, UserHandle.getUserId(callingUid))) {
String msg = String.format(
"uid %s cannot get secrets for accounts of type: %s",
@@ -572,287 +466,33 @@
accountType);
throw new SecurityException(msg);
}
- LinkedHashSet<String> allUidsForAccountType = getRequestingPackageNames(accountType, accounts);
- LinkedHashSet<Integer> uids = new LinkedHashSet<Integer>();
- for (String packageName : allUidsForAccountType) {
- try {
- int uid = mPackageManager.getPackageUid(packageName, 0);
- uids.add(uid);
- } catch (NameNotFoundException e) {
- Log.d("Package not found ", e.getMessage());
- // Skip bad package.
- }
- }
- // Add UIDs for which visibility was saved in the database.
- synchronized (accounts.cacheLock) {
- final Account[] accountsOfType = accounts.accountCache.get(accountType);
- if (accountsOfType != null) {
- for (Account account : accountsOfType) {
- final long accountId = accounts.accountsDb.findDeAccountId(account);
- if (accountId < 0) {
- continue;
- }
- Map<Integer, Integer> uidToVisibility =
- accounts.accountsDb.findAccountVisibilityForAccountId(accountId);
- uids.addAll(uidToVisibility.keySet());
- }
- }
- }
- uids.remove(AccountManager.DEFAULT_VISIBILITY);
- uids.remove(AccountManager.DEFAULT_LEGACY_VISIBILITY);
-
- // Some UIDs may contain many packages and we need to remove duplicates.
- int[] result = new int[uids.size()];
- int index = 0;
- for (Integer uid : uids) {
- result[index++] = uid;
- }
- return result;
- }
-
- /**
- * Returns all UIDs for applications that requested the account type. This method
- * is called indirectly by the Authenticator and AccountManager
- *
- * @param accountType authenticator would like to know the requesting apps of
- * @param accounts UserAccount that currently hosts the account and application
- *
- * @return ArrayList of all UIDs that support accounts of this
- * account type that seek approval (to be used to know which accounts for
- * the authenticator to include in addAccountExplicitly). Null if none.
- */
- private LinkedHashSet<String> getRequestingPackageNames(
- String accountType,
- UserAccounts accounts) {
- LinkedHashSet<String> apps = accounts.mApplicationAccountRequestMappings.get(accountType);
- if (apps == null) {
- apps = new LinkedHashSet<>();
- }
- return apps;
+ // TODO Implement.
+ return new int[]{};
}
@Override
public int getAccountVisibility(Account a, int uid) {
- int callingUid = Binder.getCallingUid();
- if (!isAccountManagedByCaller(a.type, callingUid, UserHandle.getUserId(callingUid))
- && !isSystemUid(callingUid)) {
- String msg = String.format(
- "uid %s cannot get secrets for accounts of type: %s",
- callingUid,
- a.type);
- throw new SecurityException(msg);
- }
- return getAccountVisibility(a, uid, getUserAccounts(UserHandle.getUserId(callingUid)));
- }
-
- /**
- * Method gets visibility for given account and UID from the database
- *
- * @param account The account to check visibility of
- * @param uid UID to check visibility of
- * @param accounts UserAccount that currently hosts the account and application
- *
- * @return Visibility value, AccountManager.VISIBILITY_UNDEFINED if no value was stored.
- *
- */
- private int getAccountVisibility(Account account, int uid, UserAccounts accounts) {
- final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
- try {
- Integer visibility = accounts.accountsDb.findAccountVisibility(account, uid);
- return visibility != null ? visibility : AccountManager.VISIBILITY_UNDEFINED;
- } finally {
- StrictMode.setThreadPolicy(oldPolicy);
- }
- }
-
- /**
- * Method which handles default values for Account visibility.
- *
- * @param account The account to check visibility.
- * @param uid UID to check visibility.
- * @param packageName Package name to check visibility - the method assumes that it has the same
- * uid as specified in the parameter.
- * @param accounts UserAccount that currently hosts the account and application
- *
- * @return Visibility value, the method never returns AccountManager.VISIBILITY_UNDEFINED
- *
- */
- private Integer resolveAccountVisibility(Account account, int uid, String packageName,
- UserAccounts accounts) {
-
- // Always return stored value if it was set.
- int visibility = getAccountVisibility(account, uid, accounts);
- if (AccountManager.VISIBILITY_UNDEFINED != visibility) {
- return visibility;
- }
- if (isPermittedForPackage(packageName, Manifest.permission.GET_ACCOUNTS_PRIVILEGED)) {
- return AccountManager.VISIBILITY_VISIBLE; // User can not revoke visibility for this
- // apps.
- }
-
- if (UserHandle.isSameApp(uid, Process.SYSTEM_UID)) {
- return AccountManager.VISIBILITY_VISIBLE;
- }
- int signatureCheckResult =
- checkPackageSignature(account.type, uid, UserHandle.getUserId(uid), packageName);
- if (signatureCheckResult == SIGNATURE_CHECK_UID_MATCH) { // uid match
- return AccountManager.VISIBILITY_VISIBLE; // Authenticator can always see the account
- }
-
- boolean preO = isPreOApplication(packageName);
- if ((signatureCheckResult != SIGNATURE_CHECK_MISMATCH)
- || (preO && checkGetAccountsPermission(account.type, uid, UserHandle.getUserId(uid),
- packageName))) {
- // use legacy for preO apps with GET_ACCOUNTS permission or pre/postO with signature
- // match.
- visibility = getAccountVisibility(account, AccountManager.DEFAULT_LEGACY_VISIBILITY,
- accounts);
- if (AccountManager.VISIBILITY_UNDEFINED == visibility) {
- visibility = AccountManager.VISIBILITY_USER_MANAGED_VISIBLE;
- }
- } else {
- visibility = getAccountVisibility(account, AccountManager.DEFAULT_VISIBILITY, accounts);
- if (AccountManager.VISIBILITY_UNDEFINED == visibility) {
- visibility = AccountManager.VISIBILITY_USER_MANAGED_NOT_VISIBLE;
- }
- }
-
- return visibility;
- }
-
- /**
- * Checks targetSdk for a package;
- *
- * @param packageName Package Name
- *
- * @return True if package's target SDK is below {@link android.os.Build.VERSION_CODES#O}, or
- * undefined
- */
- private boolean isPreOApplication(String packageName) {
- try {
- ApplicationInfo applicationInfo = mPackageManager.getApplicationInfo(packageName, 0);
- if (applicationInfo != null) {
- int version = applicationInfo.targetSdkVersion;
- return version < android.os.Build.VERSION_CODES.O;
- }
- return true;
- } catch (NameNotFoundException e) {
- Log.d(TAG, "Package not found " + e.getMessage());
- return true;
- }
+ // TODO Implement.
+ return 0;
}
@Override
- public boolean setAccountVisibility(Account a, int uid, int newVisibility) {
- int callingUid = Binder.getCallingUid();
- if (!isAccountManagedByCaller(a.type, callingUid, UserHandle.getUserId(callingUid))
- && !isSystemUid(callingUid)) {
- String msg = String.format(
- "uid %s cannot get secrets for accounts of type: %s",
- callingUid,
- a.type);
- throw new SecurityException(msg);
- }
- return setAccountVisibility(a, uid, getUserAccounts(UserHandle.getUserId(callingUid)),
- newVisibility);
+ public boolean setAccountVisibility(Account a, int uid, int visibility) {
+ // TODO Implement.
+ return false;
}
/**
- * Gives a certain UID, represented a application, access to an account. This method
- * is called indirectly by the Authenticator.
- *
- * @param account Account to update visibility
- * @param uid to add visibility of the Account
- * @param accounts UserAccount that currently hosts the account and application
- *
- * @return True if account visibility was changed.
- */
- private boolean setAccountVisibility(Account account, int uid, UserAccounts accounts,
- int newVisibility) {
- synchronized (accounts.cacheLock) {
- LinkedHashSet<String> interestedPackages;
- if (uid < 0) {
- interestedPackages = getRequestingPackageNames(account.type, accounts);
- } else {
- interestedPackages = new LinkedHashSet<String>();
- String[] subPackages = mPackageManager.getPackagesForUid(uid);
- if (subPackages != null) {
- Collections.addAll(interestedPackages, subPackages);
- }
- }
- Integer[] interestedPackagesVisibility = new Integer[interestedPackages.size()];
-
- final long accountId = accounts.accountsDb.findDeAccountId(account);
- if (accountId < 0) {
- return false;
- }
- int index = 0;
- for (String packageName : interestedPackages) {
- interestedPackagesVisibility[index++] =
- resolveAccountVisibility(account, uid, packageName, accounts);
- }
-
- final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
- try {
- if (!accounts.accountsDb.setAccountVisibility(accountId, uid, newVisibility)) {
- return false;
- }
- } finally {
- StrictMode.setThreadPolicy(oldPolicy);
- }
-
- index = 0;
- for (String packageName : interestedPackages) {
- int visibility = resolveAccountVisibility(account, uid, packageName, accounts);
- if (visibility != interestedPackagesVisibility[index++]) {
- sendNotification(packageName, account);
- }
- }
- return true;
- }
- }
-
- /**
- * Register application so it can receive
- *
- * @param accountTypes account types third party app is willing to support
- * @param uid of application requesting account visibility.
- * @param packageName Package name of the app requesting account updates.
- * @param notifyAuthenticator if set to true than authenticators will be notified about the app
- * via ACCOUNTS_LISTENER_PACKAGE_INSTALLED
- * @param accounts UserAccount that hosts the account and application
- */
- private void addRequestedAccountsVisibility(String[] accountTypes, int uid, String packageName,
- boolean notifyAuthenticator, UserAccounts accounts) {
- synchronized (accounts.cacheLock) {
- for (String accountType : accountTypes) {
- LinkedHashSet<String> appSet =
- accounts.mApplicationAccountRequestMappings.get(accountType);
- if (appSet == null) {
- appSet = new LinkedHashSet<>();
- appSet.add(packageName);
- accounts.mApplicationAccountRequestMappings.put(accountType, appSet);
- } else if (!appSet.contains(packageName)) {
- appSet.add(packageName);
- }
- if (notifyAuthenticator) {
- notifyAuthenticator(uid, packageName, accountType, accounts);
- }
- }
- }
- }
-
- /**
- * Caches SUPPORTED_ACCOUNT_TYPES for already installed applications, so they may receive
- * notifications about account changes.
+ * Registers the requested login account types requested by all the applications already
+ * installed on the device.
*/
private void addRequestsForPreInstalledApplications() {
List<PackageInfo> allInstalledPackages = mPackageManager.getInstalledPackages(0);
- for (PackageInfo pi : allInstalledPackages) {
+ for(PackageInfo pi : allInstalledPackages) {
int currentUid = pi.applicationInfo.uid;
- if (currentUid != -1) {
+ if(currentUid != -1) {
registerAccountTypesSupported(currentUid,
- getUserAccounts(UserHandle.getUserId(currentUid)), false /* notify */);
+ getUserAccounts(UserHandle.getUserId(currentUid)));
}
}
}
@@ -862,90 +502,49 @@
* applications manifest as well as allowing it to opt for notifications.
*
* @param uid UID of application
- * @param accounts UserAccount that currently hosts the account and application
+ * @param ua UserAccount that currently hosts the account and application
*/
- private void registerAccountTypesSupported(int uid, UserAccounts accounts, boolean notify) {
+ private void registerAccountTypesSupported(int uid, UserAccounts ua) {
/* Account types supported are drawn from the Android Manifest of the Application */
- String interestedTypes = null;
+ String interestedPackages = null;
try {
String[] allPackages = mPackageManager.getPackagesForUid(uid);
if (allPackages != null) {
- for(String aPackage : allPackages) {
+ for (String aPackage : allPackages) {
ApplicationInfo ai = mPackageManager.getApplicationInfo(aPackage,
PackageManager.GET_META_DATA);
Bundle b = ai.metaData;
- if(b == null) {
+ if (b == null) {
return;
}
- interestedTypes = b.getString(AccountManager.SUPPORTED_ACCOUNT_TYPES);
- if(interestedTypes != null) {
- addRequestedAccountsVisibility(
- interestedTypes.split(";"), uid, aPackage, notify, accounts);
- }
-
+ interestedPackages = b.getString(AccountManager.SUPPORTED_ACCOUNT_TYPES);
}
}
- } catch (NameNotFoundException e) {
- Log.d("Package not found ", e.getMessage());
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.d("NameNotFoundException", e.getMessage());
}
- }
-
- private void unregisterAccountTypesSupported(String packageName, UserAccounts accounts) {
- synchronized(accounts.cacheLock) {
- for (HashSet<String> packages : accounts.mApplicationAccountRequestMappings.values()) {
- packages.remove(packageName);
- }
+ if (interestedPackages != null) {
+ // TODO request visibility
+ // requestAccountVisibility(interestedPackages.split(";"), uid, ua);
}
}
/**
* Sends a direct intent to a package, notifying it of a visible account change.
*
- * @param packageName to send Account to
- * @param account to send to package
+ * @param desiredPackage to send Account to
+ * @param visibleAccount to send to package
*/
- private void sendNotification(String packageName, Account account) {
- // TODO remove account param?
+ private void sendNotification(String desiredPackage, Account visibleAccount) {
Intent intent = new Intent();
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
intent.setAction(AccountManager.ACTION_VISIBLE_ACCOUNTS_CHANGED);
- intent.setPackage(packageName);
- // intent.putExtra("android.accounts.KEY_ACCOUNT", (Account) account);
+ intent.setPackage(desiredPackage);
+ // TODO update documentation, add account extra if new account became visible
+ // intent.putExtra("android.accounts.KEY_ACCOUNT", (Account) visibleAccount);
mContext.sendBroadcast(intent);
}
- /**
- * Sends a direct intent to accountAuthenticator, signaling that new app with supported
- * accountType is installed.
- *
- * @param uid UID
- * @param newPackage Package Name
- * @param accounts UserAccount that currently hosts the account and application
- */
- private void notifyAuthenticator(Integer uid, String newPackage, String accountType,
- UserAccounts accounts) {
- final RegisteredServicesCache.ServiceInfo<AuthenticatorDescription> authenticatorInfo =
- mAuthenticatorCache.getServiceInfo(AuthenticatorDescription.newKey(accountType),
- accounts.userId);
- if (authenticatorInfo == null) {
- return;
- }
- String[] allPackages = mPackageManager.getPackagesForUid(authenticatorInfo.uid);
- // There may be packages with shared userId.
- if (allPackages != null) {
- for (String subPackage : allPackages) {
- Intent intent =
- new Intent(AccountManager.ACTION_ACCOUNTS_LISTENER_PACKAGE_INSTALLED);
- intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
- intent.setPackage(subPackage);
- intent.putExtra("android.intent.extra.PACKAGE_NAME", newPackage);
- mContext.sendBroadcastAsUser(intent,
- UserHandle.getUserHandleForUid(accounts.userId));
- }
-
- }
- }
-
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException {
@@ -1187,7 +786,7 @@
AccountsDb.TABLE_ACCOUNTS);
for (Account account : accountsToRemove) {
- removeAccountInternal(accounts, account, Process.SYSTEM_UID);
+ removeAccountInternal(accounts, account, Process.myUid());
}
}
}
@@ -1444,7 +1043,7 @@
private boolean isCrossUser(int callingUid, int userId) {
return (userId != UserHandle.getCallingUserId()
- && callingUid != Process.SYSTEM_UID
+ && callingUid != Process.myUid()
&& mContext.checkCallingOrSelfPermission(
android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
!= PackageManager.PERMISSION_GRANTED);
@@ -1452,7 +1051,42 @@
@Override
public boolean addAccountExplicitly(Account account, String password, Bundle extras) {
- return addAccountExplicitlyWithVisibility(account, password, extras, null);
+ Bundle.setDefusable(extras, true);
+ // clears the visible list functionality for this account because this method allows
+ // default account access to all applications for account.
+
+ final int callingUid = Binder.getCallingUid();
+ if (Log.isLoggable(TAG, Log.VERBOSE)) {
+ Log.v(TAG, "addAccountExplicitly: " + account
+ + ", caller's uid " + callingUid
+ + ", pid " + Binder.getCallingPid());
+ }
+ if (account == null) throw new IllegalArgumentException("account is null");
+ int userId = UserHandle.getCallingUserId();
+ if (!isAccountManagedByCaller(account.type, callingUid, userId)) {
+ String msg = String.format(
+ "uid %s cannot explicitly add accounts of type: %s",
+ callingUid,
+ account.type);
+ throw new SecurityException(msg);
+ }
+
+ /*
+ * Child users are not allowed to add accounts. Only the accounts that are
+ * shared by the parent profile can be added to child profile.
+ *
+ * TODO: Only allow accounts that were shared to be added by
+ * a limited user.
+ */
+
+ // fails if the account already exists
+ long identityToken = clearCallingIdentity();
+ try {
+ UserAccounts accounts = getUserAccounts(userId);
+ return addAccountInternal(accounts, account, password, extras, callingUid);
+ } finally {
+ restoreCallingIdentity(identityToken);
+ }
}
@Override
@@ -1593,8 +1227,6 @@
// TODO: Anything to do if if succedded?
// TODO: If it failed: Show error notification? Should we remove the shadow
// account to avoid retries?
- // TODO: what we do with the visibility?
-
super.onResult(result);
}
@@ -1612,7 +1244,7 @@
}
private boolean addAccountInternal(UserAccounts accounts, Account account, String password,
- Bundle extras, int callingUid, Map<Integer, Integer> uidToVisibility) {
+ Bundle extras, int callingUid) {
Bundle.setDefusable(extras, true);
if (account == null) {
return false;
@@ -1652,17 +1284,10 @@
}
}
}
-
- if (uidToVisibility != null) {
- for (Entry<Integer, Integer> entry : uidToVisibility.entrySet()) {
- setAccountVisibility(account, entry.getKey() /* uid */,
- entry.getValue() /* visibility */);
- }
- }
accounts.accountsDb.setTransactionSuccessful();
- logRecord(AccountsDb.DEBUG_ACTION_ACCOUNT_ADD, AccountsDb.TABLE_ACCOUNTS, accountId,
- accounts, callingUid);
+ logRecord(AccountsDb.DEBUG_ACTION_ACCOUNT_ADD, AccountsDb.TABLE_ACCOUNTS,
+ accountId, accounts, callingUid);
insertAccountIntoCacheLocked(accounts, account);
} finally {
@@ -1675,23 +1300,6 @@
// Only send LOGIN_ACCOUNTS_CHANGED when the database changed.
sendAccountsChangedBroadcast(accounts.userId);
-
- // Send ACTION_VISIBLE_ACCOUNT_CHANGE to apps interested in the account type.
- LinkedHashSet<String> interestedPackages = getRequestingPackageNames(account.type,
- getUserAccounts(UserHandle.getUserId(callingUid)));
- for (String packageName : interestedPackages) {
- try {
- final int uid = mPackageManager.getPackageUidAsUser(packageName,
- UserHandle.getUserId(callingUid));
- int visibility = resolveAccountVisibility(account, uid, packageName, accounts);
- if (visibility != AccountManager.VISIBILITY_NOT_VISIBLE) {
- sendNotification(packageName, account);
- }
- } catch (NameNotFoundException e) {
- // ignore
- }
-
- }
return true;
}
@@ -2119,24 +1727,6 @@
+ " is still locked. CE data will be removed later");
}
synchronized (accounts.cacheLock) {
- LinkedHashSet<String> interestedPackages =
- accounts.mApplicationAccountRequestMappings.get(account.type);
- if (interestedPackages == null) {
- interestedPackages = new LinkedHashSet<String>();
- }
- int[] visibilityForInterestedPackages = new int[interestedPackages.size()];
- int index = 0;
- for (String packageName : interestedPackages) {
- int visibility = AccountManager.VISIBILITY_NOT_VISIBLE;
- try {
- final int uid = mPackageManager.getPackageUidAsUser(packageName,
- UserHandle.getUserId(callingUid));
- visibility = resolveAccountVisibility(account, uid, packageName, accounts);
- } catch (NameNotFoundException e) {
- // ignore
- }
- visibilityForInterestedPackages[index++] = visibility;
- }
accounts.accountsDb.beginTransaction();
// Set to a dummy value, this will only be used if the database
// transaction succeeds.
@@ -2160,17 +1750,6 @@
}
if (isChanged) {
removeAccountFromCacheLocked(accounts, account);
- index = 0;
- for (String packageName : interestedPackages) {
- if ((visibilityForInterestedPackages[index]
- != AccountManager.VISIBILITY_NOT_VISIBLE)
- && (visibilityForInterestedPackages[index]
- != AccountManager.VISIBILITY_UNDEFINED)) {
- sendNotification(packageName, account);
- }
- ++index;
- }
-
// Only broadcast LOGIN_ACCOUNTS_CHANGED if a change occured.
sendAccountsChangedBroadcast(accounts.userId);
String action = userUnlocked ? AccountsDb.DEBUG_ACTION_ACCOUNT_REMOVE
@@ -2827,10 +2406,8 @@
checkKeyIntent(
Binder.getCallingUid(),
intent);
- doNotification(
- mAccounts,
- account,
- result.getString(AccountManager.KEY_AUTH_FAILED_MESSAGE),
+ doNotification(mAccounts,
+ account, result.getString(AccountManager.KEY_AUTH_FAILED_MESSAGE),
intent, "android", accounts.userId);
}
}
@@ -3715,8 +3292,7 @@
if (response == null) throw new IllegalArgumentException("response is null");
if (accountType == null) throw new IllegalArgumentException("accountType is null");
int userId = UserHandle.getCallingUserId();
- if (!isAccountManagedByCaller(accountType, callingUid, userId)
- && !isSystemUid(callingUid)) {
+ if (!isAccountManagedByCaller(accountType, callingUid, userId) && !isSystemUid(callingUid)) {
String msg = String.format(
"uid %s cannot edit authenticator properites for account type: %s",
callingUid,
@@ -3759,50 +3335,23 @@
Preconditions.checkArgumentInRange(userId, 0, Integer.MAX_VALUE, "user must be concrete");
try {
- int uid = mPackageManager.getPackageUidAsUser(packageName, userId);
+ final int uid = mPackageManager.getPackageUidAsUser(packageName, userId);
return hasAccountAccess(account, packageName, uid);
} catch (NameNotFoundException e) {
- Log.d(TAG, "Package not found " + e.getMessage());
return false;
}
}
- // Returns package with oldest target SDK for given UID.
- private String getPackageNameForUid(int uid) {
- String[] packageNames = mPackageManager.getPackagesForUid(uid);
- if (ArrayUtils.isEmpty(packageNames)) {
- return null;
- }
- // For app op checks related to permissions all packages in the UID
- // have the same app op state, so doesn't matter which one we pick.
- // Update: due to visibility changes we want to use package with oldest target SDK,
-
- String packageName = packageNames[0];
- int oldestVersion = Integer.MAX_VALUE;
- for (String name : packageNames) {
- try {
- ApplicationInfo applicationInfo = mPackageManager.getApplicationInfo(name, 0);
- if (applicationInfo != null) {
- int version = applicationInfo.targetSdkVersion;
- if (version < oldestVersion) {
- oldestVersion = version;
- packageName = name;
- }
- }
- } catch (NameNotFoundException e) {
- // skip
- }
- }
- return packageName;
- }
-
private boolean hasAccountAccess(@NonNull Account account, @Nullable String packageName,
int uid) {
if (packageName == null) {
- packageName = getPackageNameForUid(uid);
- if (packageName == null) {
+ String[] packageNames = mPackageManager.getPackagesForUid(uid);
+ if (ArrayUtils.isEmpty(packageNames)) {
return false;
}
+ // For app op checks related to permissions all packages in the UID
+ // have the same app op state, so doesn't matter which one we pick.
+ packageName = packageNames[0];
}
// Use null token which means any token. Having a token means the package
@@ -3811,12 +3360,9 @@
return true;
}
// In addition to the permissions required to get an auth token we also allow
- // the account to be accessed by apps for which user or authenticator granted visibility.
-
- int visibility = resolveAccountVisibility(account, uid, packageName,
- getUserAccounts(UserHandle.getUserId(uid)));
- return (visibility == AccountManager.VISIBILITY_VISIBLE
- || visibility == AccountManager.VISIBILITY_USER_MANAGED_VISIBLE);
+ // the account to be accessed by holders of the get accounts permissions.
+ return checkUidPermission(Manifest.permission.GET_ACCOUNTS_PRIVILEGED, uid, packageName)
+ || checkUidPermission(Manifest.permission.GET_ACCOUNTS, uid, packageName);
}
private boolean checkUidPermission(String permission, int uid, String opPackageName) {
@@ -3930,28 +3476,21 @@
private volatile ArrayList<Account> mAccountsWithFeatures = null;
private volatile int mCurrentAccount = 0;
private final int mCallingUid;
- private final String mPackageName;
- public GetAccountsByTypeAndFeatureSession(
- UserAccounts accounts,
- IAccountManagerResponse response,
- String type,
- String[] features,
- int callingUid,
- String packageName) {
+ public GetAccountsByTypeAndFeatureSession(UserAccounts accounts,
+ IAccountManagerResponse response, String type, String[] features, int callingUid) {
super(accounts, response, type, false /* expectActivityLaunch */,
true /* stripAuthTokenFromResult */, null /* accountName */,
false /* authDetailsRequired */);
mCallingUid = callingUid;
mFeatures = features;
- mPackageName = packageName;
}
@Override
public void run() throws RemoteException {
synchronized (mAccounts.cacheLock) {
mAccountsOfType = getAccountsFromCacheLocked(mAccounts, mAccountType, mCallingUid,
- mPackageName);
+ null);
}
// check whether each account matches the requested features
mAccountsWithFeatures = new ArrayList<>(mAccountsOfType.length);
@@ -4050,7 +3589,7 @@
return getAccountsInternal(
accounts,
callingUid,
- opPackageName,
+ null, // packageName
visibleAccountTypes);
} finally {
restoreCallingIdentity(identityToken);
@@ -4093,7 +3632,7 @@
if (userAccounts == null) continue;
synchronized (userAccounts.cacheLock) {
Account[] accounts = getAccountsFromCacheLocked(userAccounts, null,
- Binder.getCallingUid(), null); //TODO check package
+ Binder.getCallingUid(), null);
for (int a = 0; a < accounts.length; a++) {
runningAccounts.add(new AccountAndUser(accounts[a], userId));
}
@@ -4107,19 +3646,7 @@
@Override
@NonNull
public Account[] getAccountsAsUser(String type, int userId, String opPackageName) {
- return getAccountsAsUser(type, userId, null /* callingPackage */, -1, opPackageName);
- }
-
- @NonNull
- private Account[] filterVisibleAccounts(Map<Account, Integer> accounts) {
- ArrayList<Account> filteredAccounts = new ArrayList<>();
- for (Map.Entry<Account, Integer> entry : accounts.entrySet()) {
- if (entry.getValue() == AccountManager.VISIBILITY_VISIBLE
- || entry.getValue() == AccountManager.VISIBILITY_USER_MANAGED_VISIBLE) {
- filteredAccounts.add(entry.getKey());
- }
- }
- return filteredAccounts.toArray(new Account[filteredAccounts.size()]);
+ return getAccountsAsUser(type, userId, null, -1, opPackageName);
}
@NonNull
@@ -4132,7 +3659,7 @@
int callingUid = Binder.getCallingUid();
// Only allow the system process to read accounts of other users
if (userId != UserHandle.getCallingUserId()
- && callingUid != Process.SYSTEM_UID
+ && callingUid != Process.myUid()
&& mContext.checkCallingOrSelfPermission(
android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
!= PackageManager.PERMISSION_GRANTED) {
@@ -4145,17 +3672,9 @@
+ ", caller's uid " + Binder.getCallingUid()
+ ", pid " + Binder.getCallingPid());
}
-
- // If the original calling app was using account choosing activity
- // provided by the framework or authenticator we'll passing in
- // the original caller's uid here, which is what should be used for filtering.
- List<String> managedTypes =
- getTypesManagedByCaller(callingUid, UserHandle.getUserId(callingUid));
- if (packageUid != -1 &&
- ((UserHandle.isSameApp(callingUid, Process.SYSTEM_UID)
- || (type != null && managedTypes.contains(type))))) {
- Log.v(TAG, "getAccounts package was swithed to " + callingPackage + " from "
- + opPackageName);
+ // If the original calling app was using the framework account chooser activity, we'll
+ // be passed in the original caller's uid here, which is what should be used for filtering.
+ if (packageUid != -1 && UserHandle.isSameApp(callingUid, Process.myUid())) {
callingUid = packageUid;
opPackageName = callingPackage;
}
@@ -4163,7 +3682,7 @@
opPackageName);
if (visibleAccountTypes.isEmpty()
|| (type != null && !visibleAccountTypes.contains(type))) {
- return new Account[]{};
+ return new Account[0];
} else if (visibleAccountTypes.contains(type)) {
// Prune the list down to just the requested type.
visibleAccountTypes = new ArrayList<>();
@@ -4177,7 +3696,7 @@
return getAccountsInternal(
accounts,
callingUid,
- opPackageName,
+ callingPackage,
visibleAccountTypes);
} finally {
restoreCallingIdentity(identityToken);
@@ -4278,7 +3797,6 @@
@Override
@NonNull
public Account[] getAccounts(String type, String opPackageName) {
- Log.v(TAG, "get accounts for package " + opPackageName + " type " + type);
return getAccountsAsUser(type, UserHandle.getCallingUserId(), opPackageName);
}
@@ -4286,7 +3804,7 @@
@NonNull
public Account[] getAccountsForPackage(String packageName, int uid, String opPackageName) {
int callingUid = Binder.getCallingUid();
- if (!UserHandle.isSameApp(callingUid, Process.SYSTEM_UID)) {
+ if (!UserHandle.isSameApp(callingUid, Process.myUid())) {
throw new SecurityException("getAccountsForPackage() called from unauthorized uid "
+ callingUid + " with uid=" + uid);
}
@@ -4298,18 +3816,17 @@
@NonNull
public Account[] getAccountsByTypeForPackage(String type, String packageName,
String opPackageName) {
-
int packageUid = -1;
try {
- packageUid = AppGlobals.getPackageManager().getPackageUid(packageName,
- PackageManager.MATCH_UNINSTALLED_PACKAGES, UserHandle.getCallingUserId());
+ packageUid = AppGlobals.getPackageManager().getPackageUid(
+ packageName, PackageManager.MATCH_UNINSTALLED_PACKAGES,
+ UserHandle.getCallingUserId());
} catch (RemoteException re) {
Slog.e(TAG, "Couldn't determine the packageUid for " + packageName + re);
return new Account[0];
}
-
- return getAccountsAsUser(type, UserHandle.getCallingUserId(),
- packageName, packageUid, opPackageName);
+ return getAccountsAsUser(type, UserHandle.getCallingUserId(), packageName,
+ packageUid, opPackageName);
}
@Override
@@ -4349,8 +3866,7 @@
if (features == null || features.length == 0) {
Account[] accounts;
synchronized (userAccounts.cacheLock) {
- accounts = getAccountsFromCacheLocked(
- userAccounts, type, callingUid, opPackageName);
+ accounts = getAccountsFromCacheLocked(userAccounts, type, callingUid, null);
}
Bundle result = new Bundle();
result.putParcelableArray(AccountManager.KEY_ACCOUNTS, accounts);
@@ -4362,8 +3878,7 @@
response,
type,
features,
- callingUid,
- opPackageName).bind();
+ callingUid).bind();
} finally {
restoreCallingIdentity(identityToken);
}
@@ -4382,7 +3897,6 @@
if (Objects.equals(account.getAccessId(), token)) {
// An app just accessed the account. At this point it knows about
// it and there is not need to hide this account from the app.
- // Do we need to update account visibility here?
if (!hasAccountAccess(account, null, uid)) {
updateAppPermission(account, AccountManager.ACCOUNT_ACCESS_TOKEN_TYPE,
uid, true);
@@ -4909,7 +4423,7 @@
userAccounts.accountsDb.dumpDeAccountsTable(fout);
} else {
Account[] accounts = getAccountsFromCacheLocked(userAccounts, null /* type */,
- Process.SYSTEM_UID, null);
+ Process.myUid(), null);
fout.println("Accounts: " + accounts.length);
for (Account account : accounts) {
fout.println(" " + account);
@@ -5002,16 +4516,6 @@
}
}
- private boolean isPermittedForPackage(String opPackageName, String... permissions) {
- for (String perm : permissions) {
- if (mPackageManager.checkPermission(perm, opPackageName)
- == PackageManager.PERMISSION_GRANTED) {
- return true;
- }
- }
- return false;
- }
-
private boolean isPermitted(String opPackageName, int callingUid, String... permissions) {
for (String perm : permissions) {
if (mContext.checkCallingOrSelfPermission(perm) == PackageManager.PERMISSION_GRANTED) {
@@ -5046,7 +4550,6 @@
userPackageManager = mContext.createPackageContextAsUser(
"android", 0, new UserHandle(callingUserId)).getPackageManager();
} catch (NameNotFoundException e) {
- Log.d(TAG, "Package not found " + e.getMessage());
return false;
}
@@ -5060,7 +4563,6 @@
return true;
}
} catch (PackageManager.NameNotFoundException e) {
- Log.d(TAG, "Package not found " + e.getMessage());
return false;
}
}
@@ -5115,58 +4617,6 @@
}
}
- // Method checks visibility for applications targeing API level below {@link
- // android.os.Build.VERSION_CODES#O},
- // returns true if the the app has GET_ACCOUNTS or GET_ACCOUNTS_PRIVELEGED permission.
- private boolean checkGetAccountsPermission(String accountType, int callingUid, int userId,
- String opPackageName) {
- if (accountType == null) {
- return false;
- }
- if (isPermittedForPackage(opPackageName, Manifest.permission.GET_ACCOUNTS,
- Manifest.permission.GET_ACCOUNTS_PRIVILEGED)) {
- return true;
- }
-
- return false;
- }
-
- /**
- * Method checks package uid and signature with Authenticator which manages accountType.
- *
- * @return SIGNATURE_CHECK_UID_MATCH for uid match, SIGNATURE_CHECK_MATCH for signature match,
- * SIGNATURE_CHECK_MISMATCH otherwise.
- */
- private int checkPackageSignature(String accountType, int callingUid, int userId,
- String opPackageName) {
- if (accountType == null) {
- return SIGNATURE_CHECK_MISMATCH;
- }
-
- long identityToken = Binder.clearCallingIdentity();
- Collection<RegisteredServicesCache.ServiceInfo<AuthenticatorDescription>> serviceInfos;
- try {
- serviceInfos = mAuthenticatorCache.getAllServices(userId);
- } finally {
- Binder.restoreCallingIdentity(identityToken);
- }
- // Check for signtaure match with Authenticator.
- for (RegisteredServicesCache.ServiceInfo<AuthenticatorDescription> serviceInfo
- : serviceInfos) {
- if (accountType.equals(serviceInfo.type.type)) {
- if (serviceInfo.uid == callingUid) {
- return SIGNATURE_CHECK_UID_MATCH;
- }
- final int sigChk = mPackageManager.checkSignatures(serviceInfo.uid, callingUid);
- if (sigChk == PackageManager.SIGNATURE_MATCH) {
- return SIGNATURE_CHECK_MATCH;
- }
- }
- }
- return SIGNATURE_CHECK_MISMATCH;
- }
-
- // returns true for system apps and applications with the same signature as authenticator.
private boolean isAccountManagedByCaller(String accountType, int callingUid, int userId) {
if (accountType == null) {
return false;
@@ -5177,13 +4627,14 @@
private List<String> getTypesVisibleToCaller(int callingUid, int userId,
String opPackageName) {
- return getTypesForCaller(callingUid, userId, true /* isOtherwisePermitted*/);
+ boolean isPermitted =
+ isPermitted(opPackageName, callingUid, Manifest.permission.GET_ACCOUNTS,
+ Manifest.permission.GET_ACCOUNTS_PRIVILEGED);
+ return getTypesForCaller(callingUid, userId, isPermitted);
}
private List<String> getTypesManagedByCaller(int callingUid, int userId) {
- // System UID is considered priveleged, GET_ACCOUNTS_PRIVILEGED is not enough.
- boolean isPrivileged = UserHandle.isSameApp(callingUid, Process.SYSTEM_UID);
- return getTypesForCaller(callingUid, userId, isPrivileged);
+ return getTypesForCaller(callingUid, userId, false);
}
private List<String> getTypesForCaller(
@@ -5198,9 +4649,8 @@
}
for (RegisteredServicesCache.ServiceInfo<AuthenticatorDescription> serviceInfo :
serviceInfos) {
- if (isOtherwisePermitted || (serviceInfo.uid == callingUid)
- || (mPackageManager.checkSignatures(serviceInfo.uid, callingUid
- ) == PackageManager.SIGNATURE_MATCH)) {
+ final int sigChk = mPackageManager.checkSignatures(serviceInfo.uid, callingUid);
+ if (isOtherwisePermitted || sigChk == PackageManager.SIGNATURE_MATCH) {
managedAccountTypes.add(serviceInfo.type.type);
}
}
@@ -5282,7 +4732,7 @@
!= 0) {
return true;
}
- } catch (NameNotFoundException e) {
+ } catch (PackageManager.NameNotFoundException e) {
Log.w(TAG, String.format("Could not find package [%s]", name), e);
}
}
@@ -5473,31 +4923,10 @@
return newAccountsForType[oldLength];
}
- private Account[] filterAccounts(UserAccounts accounts, Account[] unfiltered, int callingUid,
- String callingPackage) {
- Map<Account, Integer> firstPass = new HashMap<>();
- for (Account account : unfiltered) {
- int visibility =
- resolveAccountVisibility(account, callingUid, callingPackage, accounts);
- if (visibility == AccountManager.VISIBILITY_VISIBLE
- || visibility == AccountManager.VISIBILITY_USER_MANAGED_VISIBLE) {
- firstPass.put(account, visibility);
- }
- }
- Map<Account, Integer> secondPass =
- filterSharedAccounts(accounts, firstPass, callingUid, callingPackage);
-
- Account[] filtered = new Account[secondPass.size()];
- filtered = secondPass.keySet().toArray(filtered);
- return filtered;
- }
-
- private Map<Account, Integer> filterSharedAccounts(UserAccounts userAccounts,
- Map<Account, Integer> unfiltered, int callingUid, String callingPackage) {
- // first part is to filter shared accounts.
- // unfiltered type check is not necessary.
+ private Account[] filterSharedAccounts(UserAccounts userAccounts, Account[] unfiltered,
+ int callingUid, String callingPackage) {
if (getUserManager() == null || userAccounts == null || userAccounts.userId < 0
- || callingUid == Process.SYSTEM_UID) {
+ || callingUid == Process.myUid()) {
return unfiltered;
}
UserInfo user = getUserManager().getUserInfo(userAccounts.userId);
@@ -5515,9 +4944,7 @@
}
ArrayList<Account> allowed = new ArrayList<>();
Account[] sharedAccounts = getSharedAccountsAsUser(userAccounts.userId);
- if (ArrayUtils.isEmpty(sharedAccounts)) {
- return unfiltered;
- }
+ if (sharedAccounts == null || sharedAccounts.length == 0) return unfiltered;
String requiredAccountType = "";
try {
// If there's an explicit callingPackage specified, check if that package
@@ -5537,12 +4964,9 @@
}
}
}
- } catch (NameNotFoundException e) {
- Log.d(TAG, "Package not found " + e.getMessage());
+ } catch (NameNotFoundException nnfe) {
}
- Map<Account, Integer> filtered = new HashMap<>();
- for (Map.Entry<Account, Integer> entry : unfiltered.entrySet()) {
- Account account = entry.getKey();
+ for (Account account : unfiltered) {
if (account.type.equals(requiredAccountType)) {
allowed.add(account);
} else {
@@ -5554,10 +4978,12 @@
}
}
if (!found) {
- filtered.put(account, entry.getValue());
+ allowed.add(account);
}
}
}
+ Account[] filtered = new Account[allowed.size()];
+ allowed.toArray(filtered);
return filtered;
} else {
return unfiltered;
@@ -5575,7 +5001,7 @@
if (accounts == null) {
return EMPTY_ACCOUNT_ARRAY;
} else {
- return filterAccounts(userAccounts, Arrays.copyOf(accounts, accounts.length),
+ return filterSharedAccounts(userAccounts, Arrays.copyOf(accounts, accounts.length),
callingUid, callingPackage);
}
} else {
@@ -5593,7 +5019,7 @@
accountsOfType.length);
totalLength += accountsOfType.length;
}
- return filterAccounts(userAccounts, accounts, callingUid, callingPackage);
+ return filterSharedAccounts(userAccounts, accounts, callingUid, callingPackage);
}
}
@@ -5821,21 +5247,19 @@
if (userId == 0) {
// Migrate old file, if it exists, to the new location.
// Make sure the new file doesn't already exist. A dummy file could have been
- // accidentally created in the old location,
- // causing the new one to become corrupted as well.
+ // accidentally created in the old location, causing the new one to become corrupted
+ // as well.
File oldFile = new File(systemDir, PRE_N_DATABASE_NAME);
if (oldFile.exists() && !databaseFile.exists()) {
// Check for use directory; create if it doesn't exist, else renameTo will fail
File userDir = Environment.getUserSystemDirectory(userId);
if (!userDir.exists()) {
if (!userDir.mkdirs()) {
- throw new IllegalStateException(
- "User dir cannot be created: " + userDir);
+ throw new IllegalStateException("User dir cannot be created: " + userDir);
}
}
if (!oldFile.renameTo(databaseFile)) {
- throw new IllegalStateException(
- "User dir cannot be migrated: " + databaseFile);
+ throw new IllegalStateException("User dir cannot be migrated: " + databaseFile);
}
}
}
diff --git a/services/core/java/com/android/server/accounts/AccountsDb.java b/services/core/java/com/android/server/accounts/AccountsDb.java
index 0ee20cc..5ca74711 100644
--- a/services/core/java/com/android/server/accounts/AccountsDb.java
+++ b/services/core/java/com/android/server/accounts/AccountsDb.java
@@ -355,7 +355,7 @@
boolean deleteAuthtokensByAccountIdAndType(long accountId, String authtokenType) {
SQLiteDatabase db = mDeDatabase.getWritableDatabaseUserIsUnlocked();
return db.delete(CE_TABLE_AUTHTOKENS,
- AUTHTOKENS_ACCOUNTS_ID + "=?" + " AND " + AUTHTOKENS_TYPE + "=?",
+ AUTHTOKENS_ACCOUNTS_ID + "=?" + accountId + " AND " + AUTHTOKENS_TYPE + "=?",
new String[]{String.valueOf(accountId), authtokenType}) > 0;
}
@@ -1306,4 +1306,4 @@
return new AccountsDb(deDatabaseHelper, context, preNDatabaseFile);
}
-}
+}
\ No newline at end of file