- add javadoc for the account manager
- add some checks to the AccountManagerService to keep it from crashing when a null is passed in
- cleaned up the API a bit
diff --git a/core/java/android/accounts/AccountManagerService.java b/core/java/android/accounts/AccountManagerService.java
index 3a11cb3..9c60141 100644
--- a/core/java/android/accounts/AccountManagerService.java
+++ b/core/java/android/accounts/AccountManagerService.java
@@ -154,6 +154,7 @@
private static final boolean isDebuggableMonkeyBuild =
SystemProperties.getBoolean("ro.monkey", false)
&& SystemProperties.getBoolean("ro.debuggable", false);
+ private static final Account[] EMPTY_ACCOUNT_ARRAY = new Account[]{};
static {
ACCOUNTS_CHANGED_INTENT = new Intent(AccountManager.LOGIN_ACCOUNTS_CHANGED_ACTION);
@@ -268,6 +269,10 @@
}
private String readPasswordFromDatabase(Account account) {
+ if (account == null) {
+ return null;
+ }
+
SQLiteDatabase db = mOpenHelper.getReadableDatabase();
Cursor cursor = db.query(TABLE_ACCOUNTS, new String[]{ACCOUNTS_PASSWORD},
ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?",
@@ -293,6 +298,10 @@
}
private String readUserDataFromDatabase(Account account, String key) {
+ if (account == null) {
+ return null;
+ }
+
SQLiteDatabase db = mOpenHelper.getReadableDatabase();
Cursor cursor = db.query(TABLE_EXTRAS, new String[]{EXTRAS_VALUE},
EXTRAS_ACCOUNTS_ID
@@ -364,6 +373,9 @@
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
db.beginTransaction();
try {
+ if (account == null) {
+ return false;
+ }
boolean noBroadcast = false;
if (account.type.equals(GOOGLE_ACCOUNT_TYPE)) {
// Look for the 'nobroadcast' flag and remove it since we don't want it to persist
@@ -417,6 +429,14 @@
checkManageAccountsPermission();
long identityToken = clearCallingIdentity();
try {
+ if (account == null) {
+ try {
+ response.onError(AccountManager.ERROR_CODE_BAD_ARGUMENTS, "null account");
+ } catch (RemoteException e) {
+ // it doesn't matter if we are unable to deliver this error
+ }
+ return;
+ }
new RemoveAccountSession(response, account).bind();
} finally {
restoreCallingIdentity(identityToken);
@@ -513,6 +533,9 @@
}
private boolean saveAuthTokenToDatabase(Account account, String type, String authToken) {
+ if (account == null || type == null) {
+ return false;
+ }
cancelNotification(getSigninRequiredNotificationId(account));
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
db.beginTransaction();
@@ -539,6 +562,9 @@
}
public String readAuthTokenFromDatabase(Account account, String authTokenType) {
+ if (account == null || authTokenType == null) {
+ return null;
+ }
SQLiteDatabase db = mOpenHelper.getReadableDatabase();
Cursor cursor = db.query(TABLE_AUTHTOKENS, new String[]{AUTHTOKENS_AUTHTOKEN},
AUTHTOKENS_ACCOUNTS_ID + "=(select _id FROM accounts WHERE name=? AND type=?) AND "
@@ -586,6 +612,9 @@
}
private void setPasswordInDB(Account account, String password) {
+ if (account == null) {
+ return;
+ }
ContentValues values = new ContentValues();
values.put(ACCOUNTS_PASSWORD, password);
mOpenHelper.getWritableDatabase().update(TABLE_ACCOUNTS, values,
@@ -608,23 +637,12 @@
}
}
- private void sendResult(IAccountManagerResponse response, Bundle bundle) {
- if (response != null) {
- try {
- response.onResult(bundle);
- } catch (RemoteException e) {
- // if the caller is dead then there is no one to care about remote
- // exceptions
- if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, "failure while notifying response", e);
- }
- }
- }
- }
-
public void setUserData(Account account, String key, String value) {
checkAuthenticateAccountsPermission(account);
long identityToken = clearCallingIdentity();
+ if (account == null) {
+ return;
+ }
if (account.type.equals(GOOGLE_ACCOUNT_TYPE) && key.equals("broadcast")) {
sendAccountsChangedBroadcast();
return;
@@ -637,6 +655,9 @@
}
private void writeUserdataIntoDatabase(Account account, String key, String value) {
+ if (account == null || key == null) {
+ return;
+ }
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
db.beginTransaction();
try {
@@ -685,6 +706,22 @@
long identityToken = clearCallingIdentity();
try {
+ try {
+ if (account == null) {
+ response.onError(AccountManager.ERROR_CODE_BAD_ARGUMENTS,
+ "account is null");
+ return;
+ }
+ if (authTokenType == null) {
+ response.onError(AccountManager.ERROR_CODE_BAD_ARGUMENTS,
+ "authTokenType is null");
+ return;
+ }
+ } catch (RemoteException e) {
+ // it doesn't matter if we can't deliver this error
+ return;
+ }
+
// if the caller has permission, do the peek. otherwise go the more expensive
// route of starting a Session
if (permissionGranted) {
@@ -850,6 +887,16 @@
checkManageAccountsPermission();
long identityToken = clearCallingIdentity();
try {
+ try {
+ if (authTokenType == null) {
+ response.onError(AccountManager.ERROR_CODE_BAD_ARGUMENTS,
+ "authTokenType is null");
+ return;
+ }
+ } catch (RemoteException e) {
+ // it doesn't matter if we can't deliver this error
+ return;
+ }
new Session(response, accountType, expectActivityLaunch) {
public void run() throws RemoteException {
mAuthenticator.addAccount(this, mAccountType, authTokenType, requiredFeatures,
@@ -875,6 +922,16 @@
checkManageAccountsPermission();
long identityToken = clearCallingIdentity();
try {
+ try {
+ if (account == null) {
+ response.onError(AccountManager.ERROR_CODE_BAD_ARGUMENTS,
+ "account is null");
+ return;
+ }
+ } catch (RemoteException e) {
+ // it doesn't matter if we can't deliver this error
+ return;
+ }
new Session(response, account.type, expectActivityLaunch) {
public void run() throws RemoteException {
mAuthenticator.confirmCredentials(this, account, options);
@@ -895,6 +952,16 @@
checkManageAccountsPermission();
long identityToken = clearCallingIdentity();
try {
+ try {
+ if (account == null) {
+ response.onError(AccountManager.ERROR_CODE_BAD_ARGUMENTS,
+ "account is null");
+ return;
+ }
+ } catch (RemoteException e) {
+ // it doesn't matter if we can't deliver this error
+ return;
+ }
new Session(response, account.type, expectActivityLaunch) {
public void run() throws RemoteException {
mAuthenticator.updateCredentials(this, account, authTokenType, loginOptions);
@@ -917,6 +984,16 @@
checkManageAccountsPermission();
long identityToken = clearCallingIdentity();
try {
+ try {
+ if (accountType == null) {
+ response.onError(AccountManager.ERROR_CODE_BAD_ARGUMENTS,
+ "accountType is null");
+ return;
+ }
+ } catch (RemoteException e) {
+ // it doesn't matter if we can't deliver this error
+ return;
+ }
new Session(response, accountType, expectActivityLaunch) {
public void run() throws RemoteException {
mAuthenticator.editProperties(this, mAccountType);
@@ -1565,8 +1642,10 @@
}
private boolean permissionIsGranted(Account account, String authTokenType, int callerUid) {
- final boolean fromAuthenticator = hasAuthenticatorUid(account.type, callerUid);
- final boolean hasExplicitGrants = hasExplicitlyGrantedPermission(account, authTokenType);
+ final boolean fromAuthenticator = account != null
+ && hasAuthenticatorUid(account.type, callerUid);
+ final boolean hasExplicitGrants = account != null
+ && hasExplicitlyGrantedPermission(account, authTokenType);
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "checkGrantsOrCallingUidAgainstAuthenticator: caller uid "
+ callerUid + ", account " + account
@@ -1610,7 +1689,7 @@
private void checkCallingUidAgainstAuthenticator(Account account) {
final int uid = Binder.getCallingUid();
- if (!hasAuthenticatorUid(account.type, uid)) {
+ if (account == null || !hasAuthenticatorUid(account.type, uid)) {
String msg = "caller uid " + uid + " is different than the authenticator's uid";
Log.w(TAG, msg);
throw new SecurityException(msg);
@@ -1641,6 +1720,9 @@
* @hide
*/
public void grantAppPermission(Account account, String authTokenType, int uid) {
+ if (account == null || authTokenType == null) {
+ return;
+ }
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
db.beginTransaction();
try {
@@ -1668,6 +1750,9 @@
* @hide
*/
public void revokeAppPermission(Account account, String authTokenType, int uid) {
+ if (account == null || authTokenType == null) {
+ return;
+ }
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
db.beginTransaction();
try {