summaryrefslogtreecommitdiffstats
path: root/core/java/android
diff options
context:
space:
mode:
authorFred Quintana <fredq@google.com>2009-08-15 21:45:26 -0700
committerFred Quintana <fredq@google.com>2009-08-15 22:40:25 -0700
commitffd0cb04f97e62d286d185c520580d81a9c328b1 (patch)
treed864589d0cfa54abc971091b172d1497cb79adcb /core/java/android
parentfa2944d93f4c5050fb4a99d90006791c2995b31c (diff)
downloadframeworks_base-ffd0cb04f97e62d286d185c520580d81a9c328b1.zip
frameworks_base-ffd0cb04f97e62d286d185c520580d81a9c328b1.tar.gz
frameworks_base-ffd0cb04f97e62d286d185c520580d81a9c328b1.tar.bz2
do not merge: cherrypicked 3710f390968e683a0ad3adf0b517dfcade3564ce from master branch
Diffstat (limited to 'core/java/android')
-rw-r--r--core/java/android/accounts/AbstractAccountAuthenticator.java25
-rw-r--r--core/java/android/accounts/Account.java24
-rw-r--r--core/java/android/accounts/AccountManager.java763
-rw-r--r--core/java/android/accounts/AccountManagerCallback.java (renamed from core/java/android/accounts/Future1Callback.java)6
-rw-r--r--core/java/android/accounts/AccountManagerFuture.java65
-rw-r--r--core/java/android/accounts/AccountManagerService.java344
-rw-r--r--core/java/android/accounts/ChooseAccountActivity.java6
-rw-r--r--core/java/android/accounts/Constants.java1
-rw-r--r--core/java/android/accounts/Future1.java46
-rw-r--r--core/java/android/accounts/Future2.java57
-rw-r--r--core/java/android/accounts/Future2Callback.java20
-rw-r--r--core/java/android/accounts/GrantCredentialsPermissionActivity.java4
-rw-r--r--core/java/android/accounts/IAccountAuthenticator.aidl5
-rw-r--r--core/java/android/accounts/IAccountManager.aidl9
-rw-r--r--core/java/android/content/AbstractSyncableContentProvider.java6
-rw-r--r--core/java/android/content/AbstractTableMerger.java6
-rw-r--r--core/java/android/content/SyncManager.java16
-rw-r--r--core/java/android/content/SyncStateContentProviderHelper.java8
-rw-r--r--core/java/android/content/SyncStorageEngine.java4
-rw-r--r--core/java/android/provider/Calendar.java2
-rw-r--r--core/java/android/provider/SubscribedFeeds.java8
-rw-r--r--core/java/android/provider/SyncStateContract.java10
22 files changed, 629 insertions, 806 deletions
diff --git a/core/java/android/accounts/AbstractAccountAuthenticator.java b/core/java/android/accounts/AbstractAccountAuthenticator.java
index 3ce3ca3..38ae962 100644
--- a/core/java/android/accounts/AbstractAccountAuthenticator.java
+++ b/core/java/android/accounts/AbstractAccountAuthenticator.java
@@ -188,6 +188,25 @@ public abstract class AbstractAccountAuthenticator {
response.onResult(result);
}
}
+
+ public void getAccountRemovalAllowed(IAccountAuthenticatorResponse response,
+ Account account) throws RemoteException {
+ checkBinderPermission();
+ try {
+ final Bundle result = AbstractAccountAuthenticator.this.getAccountRemovalAllowed(
+ new AccountAuthenticatorResponse(response), account);
+ if (result != null) {
+ response.onResult(result);
+ }
+ } catch (UnsupportedOperationException e) {
+ response.onError(Constants.ERROR_CODE_UNSUPPORTED_OPERATION,
+ "getAccountRemovalAllowed not supported");
+ return;
+ } catch (NetworkErrorException e) {
+ response.onError(Constants.ERROR_CODE_NETWORK_ERROR, e.getMessage());
+ return;
+ }
+ }
}
private void checkBinderPermission() {
@@ -238,4 +257,10 @@ public abstract class AbstractAccountAuthenticator {
Account account, String authTokenType, Bundle loginOptions);
public abstract Bundle hasFeatures(AccountAuthenticatorResponse response,
Account account, String[] features) throws NetworkErrorException;
+ public Bundle getAccountRemovalAllowed(AccountAuthenticatorResponse response,
+ Account account) throws NetworkErrorException {
+ final Bundle result = new Bundle();
+ result.putBoolean(Constants.BOOLEAN_RESULT_KEY, true);
+ return result;
+ }
}
diff --git a/core/java/android/accounts/Account.java b/core/java/android/accounts/Account.java
index 30c91b0..7b83a30 100644
--- a/core/java/android/accounts/Account.java
+++ b/core/java/android/accounts/Account.java
@@ -26,20 +26,20 @@ import android.text.TextUtils;
* suitable for use as the key of a {@link java.util.Map}
*/
public class Account implements Parcelable {
- public final String mName;
- public final String mType;
+ public final String name;
+ public final String type;
public boolean equals(Object o) {
if (o == this) return true;
if (!(o instanceof Account)) return false;
final Account other = (Account)o;
- return mName.equals(other.mName) && mType.equals(other.mType);
+ return name.equals(other.name) && type.equals(other.type);
}
public int hashCode() {
int result = 17;
- result = 31 * result + mName.hashCode();
- result = 31 * result + mType.hashCode();
+ result = 31 * result + name.hashCode();
+ result = 31 * result + type.hashCode();
return result;
}
@@ -50,13 +50,13 @@ public class Account implements Parcelable {
if (TextUtils.isEmpty(type)) {
throw new IllegalArgumentException("the type must not be empty: " + type);
}
- mName = name;
- mType = type;
+ this.name = name;
+ this.type = type;
}
public Account(Parcel in) {
- mName = in.readString();
- mType = in.readString();
+ this.name = in.readString();
+ this.type = in.readString();
}
public int describeContents() {
@@ -64,8 +64,8 @@ public class Account implements Parcelable {
}
public void writeToParcel(Parcel dest, int flags) {
- dest.writeString(mName);
- dest.writeString(mType);
+ dest.writeString(name);
+ dest.writeString(type);
}
public static final Creator<Account> CREATOR = new Creator<Account>() {
@@ -79,6 +79,6 @@ public class Account implements Parcelable {
};
public String toString() {
- return "Account {name=" + mName + ", type=" + mType + "}";
+ return "Account {name=" + name + ", type=" + type + "}";
}
}
diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java
index 502abbb..9f70534 100644
--- a/core/java/android/accounts/AccountManager.java
+++ b/core/java/android/accounts/AccountManager.java
@@ -26,8 +26,6 @@ import android.os.Handler;
import android.os.Looper;
import android.os.RemoteException;
import android.os.Parcelable;
-import android.util.Config;
-import android.util.Log;
import java.io.IOException;
import java.util.concurrent.Callable;
@@ -80,258 +78,132 @@ public class AccountManager {
return (AccountManager) context.getSystemService(Context.ACCOUNT_SERVICE);
}
- public String blockingGetPassword(Account account) {
- ensureNotOnMainThread();
+ public String getPassword(final Account account) {
try {
return mService.getPassword(account);
} catch (RemoteException e) {
- // if this happens the entire runtime will restart
+ // will never happen
throw new RuntimeException(e);
}
}
- public Future1<String> getPassword(final Future1Callback<String> callback,
- final Account account, final Handler handler) {
- return startAsFuture(callback, handler, new Callable<String>() {
- public String call() throws Exception {
- return blockingGetPassword(account);
- }
- });
- }
-
- public String blockingGetUserData(Account account, String key) {
- ensureNotOnMainThread();
+ public String getUserData(final Account account, final String key) {
try {
return mService.getUserData(account, key);
} catch (RemoteException e) {
- // if this happens the entire runtime will restart
+ // will never happen
throw new RuntimeException(e);
}
}
- public Future1<String> getUserData(Future1Callback<String> callback,
- final Account account, final String key, Handler handler) {
- return startAsFuture(callback, handler, new Callable<String>() {
- public String call() throws Exception {
- return blockingGetUserData(account, key);
- }
- });
- }
-
- public AuthenticatorDescription[] blockingGetAuthenticatorTypes() {
- ensureNotOnMainThread();
+ public AuthenticatorDescription[] getAuthenticatorTypes() {
try {
return mService.getAuthenticatorTypes();
} catch (RemoteException e) {
- // if this happens the entire runtime will restart
+ // will never happen
throw new RuntimeException(e);
}
}
- public Future1<AuthenticatorDescription[]> getAuthenticatorTypes(
- Future1Callback<AuthenticatorDescription[]> callback, Handler handler) {
- return startAsFuture(callback, handler, new Callable<AuthenticatorDescription[]>() {
- public AuthenticatorDescription[] call() throws Exception {
- return blockingGetAuthenticatorTypes();
- }
- });
- }
-
- public Account[] blockingGetAccounts() {
- ensureNotOnMainThread();
+ public Account[] getAccounts() {
try {
- return mService.getAccounts();
+ return mService.getAccounts(null);
} catch (RemoteException e) {
- // if this happens the entire runtime will restart
+ // won't ever happen
throw new RuntimeException(e);
}
}
- public Account[] blockingGetAccountsByType(String accountType) {
- ensureNotOnMainThread();
+ public Account[] getAccountsByType(String type) {
try {
- return mService.getAccountsByType(accountType);
+ return mService.getAccounts(type);
} catch (RemoteException e) {
- // if this happens the entire runtime will restart
+ // won't ever happen
throw new RuntimeException(e);
}
}
- public Future1<Account[]> getAccounts(Future1Callback<Account[]> callback, Handler handler) {
- return startAsFuture(callback, handler, new Callable<Account[]>() {
- public Account[] call() throws Exception {
- return blockingGetAccounts();
- }
- });
- }
-
- public Future1<Account[]> getAccountsByType(Future1Callback<Account[]> callback,
- final String type, Handler handler) {
- return startAsFuture(callback, handler, new Callable<Account[]>() {
- public Account[] call() throws Exception {
- return blockingGetAccountsByType(type);
- }
- });
- }
-
- public boolean blockingAddAccountExplicitly(Account account, String password, Bundle extras) {
- ensureNotOnMainThread();
+ public boolean addAccountExplicitly(Account account, String password, Bundle extras) {
try {
return mService.addAccount(account, password, extras);
} catch (RemoteException e) {
- // if this happens the entire runtime will restart
+ // won't ever happen
throw new RuntimeException(e);
}
}
- public Future1<Boolean> addAccountExplicitly(final Future1Callback<Boolean> callback,
- final Account account, final String password, final Bundle extras,
- final Handler handler) {
- return startAsFuture(callback, handler, new Callable<Boolean>() {
- public Boolean call() throws Exception {
- return blockingAddAccountExplicitly(account, password, extras);
+ public AccountManagerFuture<Boolean> removeAccount(final Account account,
+ AccountManagerCallback<Boolean> callback, Handler handler) {
+ return new Future2Task<Boolean>(handler, callback) {
+ public void doWork() throws RemoteException {
+ mService.removeAccount(mResponse, account);
}
- });
- }
-
- public void blockingRemoveAccount(Account account) {
- ensureNotOnMainThread();
- try {
- mService.removeAccount(account);
- } catch (RemoteException e) {
- // if this happens the entire runtime will restart
- }
- }
-
- public Future1<Void> removeAccount(Future1Callback<Void> callback, final Account account,
- final Handler handler) {
- return startAsFuture(callback, handler, new Callable<Void>() {
- public Void call() throws Exception {
- blockingRemoveAccount(account);
- return null;
+ public Boolean bundleToResult(Bundle bundle) throws AuthenticatorException {
+ if (!bundle.containsKey(Constants.BOOLEAN_RESULT_KEY)) {
+ throw new AuthenticatorException("no result in response");
+ }
+ return bundle.getBoolean(Constants.BOOLEAN_RESULT_KEY);
}
- });
+ }.start();
}
- public void blockingInvalidateAuthToken(String accountType, String authToken) {
- ensureNotOnMainThread();
+ public void invalidateAuthToken(final String accountType, final String authToken) {
try {
mService.invalidateAuthToken(accountType, authToken);
} catch (RemoteException e) {
- // if this happens the entire runtime will restart
+ // won't ever happen
+ throw new RuntimeException(e);
}
}
- public Future1<Void> invalidateAuthToken(Future1Callback<Void> callback,
- final String accountType, final String authToken, final Handler handler) {
- return startAsFuture(callback, handler, new Callable<Void>() {
- public Void call() throws Exception {
- blockingInvalidateAuthToken(accountType, authToken);
- return null;
- }
- });
- }
-
- public String blockingPeekAuthToken(Account account, String authTokenType) {
- ensureNotOnMainThread();
+ public String peekAuthToken(final Account account, final String authTokenType) {
try {
return mService.peekAuthToken(account, authTokenType);
} catch (RemoteException e) {
- // if this happens the entire runtime will restart
+ // won't ever happen
throw new RuntimeException(e);
}
}
- public Future1<String> peekAuthToken(Future1Callback<String> callback,
- final Account account, final String authTokenType, final Handler handler) {
- return startAsFuture(callback, handler, new Callable<String>() {
- public String call() throws Exception {
- return blockingPeekAuthToken(account, authTokenType);
- }
- });
- }
-
- public void blockingSetPassword(Account account, String password) {
- ensureNotOnMainThread();
+ public void setPassword(final Account account, final String password) {
try {
mService.setPassword(account, password);
} catch (RemoteException e) {
- // if this happens the entire runtime will restart
+ // won't ever happen
+ throw new RuntimeException(e);
}
}
- public Future1<Void> setPassword(Future1Callback<Void> callback,
- final Account account, final String password, final Handler handler) {
- return startAsFuture(callback, handler, new Callable<Void>() {
- public Void call() throws Exception {
- blockingSetPassword(account, password);
- return null;
- }
- });
- }
-
- public void blockingClearPassword(Account account) {
- ensureNotOnMainThread();
+ public void clearPassword(final Account account) {
try {
mService.clearPassword(account);
} catch (RemoteException e) {
- // if this happens the entire runtime will restart
+ // won't ever happen
+ throw new RuntimeException(e);
}
}
- public Future1<Void> clearPassword(final Future1Callback<Void> callback, final Account account,
- final Handler handler) {
- return startAsFuture(callback, handler, new Callable<Void>() {
- public Void call() throws Exception {
- blockingClearPassword(account);
- return null;
- }
- });
- }
-
- public void blockingSetUserData(Account account, String key, String value) {
- ensureNotOnMainThread();
+ public void setUserData(final Account account, final String key, final String value) {
try {
mService.setUserData(account, key, value);
} catch (RemoteException e) {
- // if this happens the entire runtime will restart
+ // won't ever happen
+ throw new RuntimeException(e);
}
}
- public Future1<Void> setUserData(Future1Callback<Void> callback,
- final Account account, final String key, final String value, final Handler handler) {
- return startAsFuture(callback, handler, new Callable<Void>() {
- public Void call() throws Exception {
- blockingSetUserData(account, key, value);
- return null;
- }
- });
- }
-
- public void blockingSetAuthToken(Account account, String authTokenType, String authToken) {
- ensureNotOnMainThread();
+ public void setAuthToken(Account account, final String authTokenType, final String authToken) {
try {
mService.setAuthToken(account, authTokenType, authToken);
} catch (RemoteException e) {
- // if this happens the entire runtime will restart
+ // won't ever happen
+ throw new RuntimeException(e);
}
}
- public Future1<Void> setAuthToken(Future1Callback<Void> callback,
- final Account account, final String authTokenType, final String authToken,
- final Handler handler) {
- return startAsFuture(callback, handler, new Callable<Void>() {
- public Void call() throws Exception {
- blockingSetAuthToken(account, authTokenType, authToken);
- return null;
- }
- });
- }
-
public String blockingGetAuthToken(Account account, String authTokenType,
boolean notifyAuthFailure)
throws OperationCanceledException, IOException, AuthenticatorException {
- ensureNotOnMainThread();
Bundle bundle = getAuthToken(account, authTokenType, notifyAuthFailure, null /* callback */,
null /* handler */).getResult();
return bundle.getString(Constants.AUTHTOKEN_KEY);
@@ -349,9 +221,9 @@ public class AccountManager {
* @param loginOptions
* @param activity the activity to launch the login intent, if necessary, and to which
*/
- public Future2 getAuthToken(
+ public AccountManagerFuture<Bundle> getAuthToken(
final Account account, final String authTokenType, final Bundle loginOptions,
- final Activity activity, Future2Callback callback, Handler handler) {
+ final Activity activity, AccountManagerCallback<Bundle> callback, Handler handler) {
if (activity == null) throw new IllegalArgumentException("activity is null");
if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null");
return new AmsTask(activity, handler, callback) {
@@ -363,9 +235,9 @@ public class AccountManager {
}.start();
}
- public Future2 getAuthToken(
+ public AccountManagerFuture<Bundle> getAuthToken(
final Account account, final String authTokenType, final boolean notifyAuthFailure,
- Future2Callback callback, Handler handler) {
+ AccountManagerCallback<Bundle> callback, Handler handler) {
if (account == null) throw new IllegalArgumentException("account is null");
if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null");
return new AmsTask(null, handler, callback) {
@@ -376,10 +248,10 @@ public class AccountManager {
}.start();
}
- public Future2 addAccount(final String accountType,
+ public AccountManagerFuture<Bundle> addAccount(final String accountType,
final String authTokenType, final String[] requiredFeatures,
final Bundle addAccountOptions,
- final Activity activity, Future2Callback callback, Handler handler) {
+ final Activity activity, AccountManagerCallback<Bundle> callback, Handler handler) {
return new AmsTask(activity, handler, callback) {
public void doWork() throws RemoteException {
mService.addAcount(mResponse, accountType, authTokenType,
@@ -389,44 +261,45 @@ public class AccountManager {
}
/** @deprecated use {@link #confirmCredentials} instead */
- public Future1<Boolean> confirmPassword(final Account account, final String password,
- Future1Callback<Boolean> callback, Handler handler) {
- return new AMSTaskBoolean(handler, callback) {
+ public AccountManagerFuture<Boolean> confirmPassword(final Account account, final String password,
+ AccountManagerCallback<Boolean> callback, Handler handler) {
+ return new Future2Task<Boolean>(handler, callback) {
public void doWork() throws RemoteException {
- mService.confirmPassword(response, account, password);
+ mService.confirmPassword(mResponse, account, password);
}
- };
- }
-
- public Account[] blockingGetAccountsWithTypeAndFeatures(String type, String[] features)
- throws AuthenticatorException, IOException, OperationCanceledException {
- Future2 future = getAccountsWithTypeAndFeatures(type, features,
- null /* callback */, null /* handler */);
- Bundle result = future.getResult();
- Parcelable[] accountsTemp = result.getParcelableArray(Constants.ACCOUNTS_KEY);
- if (accountsTemp == null) {
- throw new AuthenticatorException("accounts should not be null");
- }
- Account[] accounts = new Account[accountsTemp.length];
- for (int i = 0; i < accountsTemp.length; i++) {
- accounts[i] = (Account) accountsTemp[i];
- }
- return accounts;
+ public Boolean bundleToResult(Bundle bundle) throws AuthenticatorException {
+ if (!bundle.containsKey(Constants.BOOLEAN_RESULT_KEY)) {
+ throw new AuthenticatorException("no result in response");
+ }
+ return bundle.getBoolean(Constants.BOOLEAN_RESULT_KEY);
+ }
+ }.start();
}
- public Future2 getAccountsWithTypeAndFeatures(
+ public AccountManagerFuture<Account[]> getAccountsByTypeAndFeatures(
final String type, final String[] features,
- Future2Callback callback, Handler handler) {
+ AccountManagerCallback<Account[]> callback, Handler handler) {
if (type == null) throw new IllegalArgumentException("type is null");
- return new AmsTask(null /* activity */, handler, callback) {
+ return new Future2Task<Account[]>(handler, callback) {
public void doWork() throws RemoteException {
- mService.getAccountsByTypeAndFeatures(mResponse, type, features);
+ mService.getAccountsByFeatures(mResponse, type, features);
+ }
+ public Account[] bundleToResult(Bundle bundle) throws AuthenticatorException {
+ if (!bundle.containsKey(Constants.ACCOUNTS_KEY)) {
+ throw new AuthenticatorException("no result in response");
+ }
+ final Parcelable[] parcelables = bundle.getParcelableArray(Constants.ACCOUNTS_KEY);
+ Account[] descs = new Account[parcelables.length];
+ for (int i = 0; i < parcelables.length; i++) {
+ descs[i] = (Account) parcelables[i];
+ }
+ return descs;
}
}.start();
}
- public Future2 confirmCredentials(final Account account, final Activity activity,
- final Future2Callback callback,
+ public AccountManagerFuture<Bundle> confirmCredentials(final Account account, final Activity activity,
+ final AccountManagerCallback<Bundle> callback,
final Handler handler) {
return new AmsTask(activity, handler, callback) {
public void doWork() throws RemoteException {
@@ -435,9 +308,9 @@ public class AccountManager {
}.start();
}
- public Future2 updateCredentials(final Account account, final String authTokenType,
+ public AccountManagerFuture<Bundle> updateCredentials(final Account account, final String authTokenType,
final Bundle loginOptions, final Activity activity,
- final Future2Callback callback,
+ final AccountManagerCallback<Bundle> callback,
final Handler handler) {
return new AmsTask(activity, handler, callback) {
public void doWork() throws RemoteException {
@@ -447,8 +320,8 @@ public class AccountManager {
}.start();
}
- public Future2 editProperties(final String accountType, final Activity activity,
- final Future2Callback callback,
+ public AccountManagerFuture<Bundle> editProperties(final String accountType, final Activity activity,
+ final AccountManagerCallback<Bundle> callback,
final Handler handler) {
return new AmsTask(activity, handler, callback) {
public void doWork() throws RemoteException {
@@ -471,8 +344,8 @@ public class AccountManager {
}
}
- private void postToHandler(Handler handler, final Future2Callback callback,
- final Future2 future) {
+ private void postToHandler(Handler handler, final AccountManagerCallback<Bundle> callback,
+ final AccountManagerFuture<Bundle> future) {
handler = handler == null ? mMainHandler : handler;
handler.post(new Runnable() {
public void run() {
@@ -483,87 +356,24 @@ public class AccountManager {
private void postToHandler(Handler handler, final OnAccountsUpdatedListener listener,
final Account[] accounts) {
- handler = handler == null ? mMainHandler : handler;
- handler.post(new Runnable() {
- public void run() {
- listener.onAccountsUpdated(accounts);
- }
- });
- }
-
- private <V> void postToHandler(Handler handler, final Future1Callback<V> callback,
- final Future1<V> future) {
- handler = handler == null ? mMainHandler : handler;
+ final Account[] accountsCopy = new Account[accounts.length];
+ // send a copy to make sure that one doesn't
+ // change what another sees
+ System.arraycopy(accounts, 0, accountsCopy, 0, accountsCopy.length);
+ handler = (handler == null) ? mMainHandler : handler;
handler.post(new Runnable() {
public void run() {
- callback.run(future);
+ listener.onAccountsUpdated(accountsCopy);
}
});
}
- private <V> Future1<V> startAsFuture(Future1Callback<V> callback, Handler handler,
- Callable<V> callable) {
- final FutureTaskWithCallback<V> task =
- new FutureTaskWithCallback<V>(callback, callable, handler);
- new Thread(task).start();
- return task;
- }
-
- private class FutureTaskWithCallback<V> extends FutureTask<V> implements Future1<V> {
- final Future1Callback<V> mCallback;
- final Handler mHandler;
-
- public FutureTaskWithCallback(Future1Callback<V> callback, Callable<V> callable,
- Handler handler) {
- super(callable);
- mCallback = callback;
- mHandler = handler;
- }
-
- protected void done() {
- if (mCallback != null) {
- postToHandler(mHandler, mCallback, this);
- }
- }
-
- public V internalGetResult(Long timeout, TimeUnit unit) throws OperationCanceledException {
- try {
- if (timeout == null) {
- return get();
- } else {
- return get(timeout, unit);
- }
- } catch (InterruptedException e) {
- // we will cancel the task below
- } catch (CancellationException e) {
- // we will cancel the task below
- } catch (TimeoutException e) {
- // we will cancel the task below
- } catch (ExecutionException e) {
- // this should never happen
- throw new IllegalStateException(e.getCause());
- } finally {
- cancel(true /* interruptIfRunning */);
- }
- throw new OperationCanceledException();
- }
-
- public V getResult() throws OperationCanceledException {
- return internalGetResult(null, null);
- }
-
- public V getResult(long timeout, TimeUnit unit) throws OperationCanceledException {
- return internalGetResult(null, null);
- }
- }
-
- private abstract class AmsTask extends FutureTask<Bundle> implements Future2 {
+ private abstract class AmsTask extends FutureTask<Bundle> implements AccountManagerFuture<Bundle> {
final IAccountManagerResponse mResponse;
final Handler mHandler;
- final Future2Callback mCallback;
+ final AccountManagerCallback<Bundle> mCallback;
final Activity mActivity;
- final Thread mThread;
- public AmsTask(Activity activity, Handler handler, Future2Callback callback) {
+ public AmsTask(Activity activity, Handler handler, AccountManagerCallback<Bundle> callback) {
super(new Callable<Bundle>() {
public Bundle call() throws Exception {
throw new IllegalStateException("this should never be called");
@@ -574,19 +384,14 @@ public class AccountManager {
mCallback = callback;
mActivity = activity;
mResponse = new Response();
- mThread = new Thread(new Runnable() {
- public void run() {
- try {
- doWork();
- } catch (RemoteException e) {
- // never happens
- }
- }
- }, "AmsTask");
}
- public final Future2 start() {
- mThread.start();
+ public final AccountManagerFuture<Bundle> start() {
+ try {
+ doWork();
+ } catch (RemoteException e) {
+ setException(e);
+ }
return this;
}
@@ -594,6 +399,7 @@ public class AccountManager {
private Bundle internalGetResult(Long timeout, TimeUnit unit)
throws OperationCanceledException, IOException, AuthenticatorException {
+ ensureNotOnMainThread();
try {
if (timeout == null) {
return get();
@@ -676,42 +482,90 @@ public class AccountManager {
}
- private abstract class AMSTaskBoolean extends FutureTask<Boolean> implements Future1<Boolean> {
- final IAccountManagerResponse response;
+ private abstract class BaseFutureTask<T> extends FutureTask<T> {
+ final public IAccountManagerResponse mResponse;
final Handler mHandler;
- final Future1Callback<Boolean> mCallback;
- public AMSTaskBoolean(Handler handler, Future1Callback<Boolean> callback) {
- super(new Callable<Boolean>() {
- public Boolean call() throws Exception {
+
+ public BaseFutureTask(Handler handler) {
+ super(new Callable<T>() {
+ public T call() throws Exception {
throw new IllegalStateException("this should never be called");
}
});
-
mHandler = handler;
- mCallback = callback;
- response = new Response();
+ mResponse = new Response();
+ }
- new Thread(new Runnable() {
- public void run() {
- try {
- doWork();
- } catch (RemoteException e) {
- // never happens
+ public abstract void doWork() throws RemoteException;
+
+ public abstract T bundleToResult(Bundle bundle) throws AuthenticatorException;
+
+ protected void postRunnableToHandler(Runnable runnable) {
+ Handler handler = (mHandler == null) ? mMainHandler : mHandler;
+ handler.post(runnable);
+ }
+
+ protected void startTask() {
+ try {
+ doWork();
+ } catch (RemoteException e) {
+ setException(e);
+ }
+ }
+
+ protected class Response extends IAccountManagerResponse.Stub {
+ public void onResult(Bundle bundle) {
+ try {
+ T result = bundleToResult(bundle);
+ if (result == null) {
+ return;
}
+ set(result);
+ return;
+ } catch (ClassCastException e) {
+ // we will set the exception below
+ } catch (AuthenticatorException e) {
+ // we will set the exception below
}
- }).start();
- }
+ onError(Constants.ERROR_CODE_INVALID_RESPONSE, "no result in response");
+ }
- public abstract void doWork() throws RemoteException;
+ public void onError(int code, String message) {
+ if (code == Constants.ERROR_CODE_CANCELED) {
+ cancel(true /* mayInterruptIfRunning */);
+ return;
+ }
+ setException(convertErrorToException(code, message));
+ }
+ }
+ }
+ private abstract class Future2Task<T>
+ extends BaseFutureTask<T> implements AccountManagerFuture<T> {
+ final AccountManagerCallback<T> mCallback;
+ public Future2Task(Handler handler, AccountManagerCallback<T> callback) {
+ super(handler);
+ mCallback = callback;
+ }
protected void done() {
if (mCallback != null) {
- postToHandler(mHandler, mCallback, this);
+ postRunnableToHandler(new Runnable() {
+ public void run() {
+ mCallback.run(Future2Task.this);
+ }
+ });
}
}
- private Boolean internalGetResult(Long timeout, TimeUnit unit) {
+ public Future2Task<T> start() {
+ startTask();
+ return this;
+ }
+
+ private T internalGetResult(Long timeout, TimeUnit unit)
+ throws OperationCanceledException, IOException, AuthenticatorException {
+ ensureNotOnMainThread();
try {
if (timeout == null) {
return get();
@@ -723,15 +577,15 @@ public class AccountManager {
} catch (TimeoutException e) {
// fall through and cancel
} catch (CancellationException e) {
- return false;
+ // fall through and cancel
} catch (ExecutionException e) {
final Throwable cause = e.getCause();
if (cause instanceof IOException) {
- return false;
+ throw (IOException) cause;
} else if (cause instanceof UnsupportedOperationException) {
- return false;
+ throw new AuthenticatorException(cause);
} else if (cause instanceof AuthenticatorException) {
- return false;
+ throw (AuthenticatorException) cause;
} else if (cause instanceof RuntimeException) {
throw (RuntimeException) cause;
} else if (cause instanceof Error) {
@@ -742,39 +596,19 @@ public class AccountManager {
} finally {
cancel(true /* interrupt if running */);
}
- return false;
+ throw new OperationCanceledException();
}
- public Boolean getResult() throws OperationCanceledException {
+ public T getResult()
+ throws OperationCanceledException, IOException, AuthenticatorException {
return internalGetResult(null, null);
}
- public Boolean getResult(long timeout, TimeUnit unit) throws OperationCanceledException {
+ public T getResult(long timeout, TimeUnit unit)
+ throws OperationCanceledException, IOException, AuthenticatorException {
return internalGetResult(timeout, unit);
}
- private class Response extends IAccountManagerResponse.Stub {
- public void onResult(Bundle bundle) {
- try {
- if (bundle.containsKey(Constants.BOOLEAN_RESULT_KEY)) {
- set(bundle.getBoolean(Constants.BOOLEAN_RESULT_KEY));
- return;
- }
- } catch (ClassCastException e) {
- // we will set the exception below
- }
- onError(Constants.ERROR_CODE_INVALID_RESPONSE, "no result in response");
- }
-
- public void onError(int code, String message) {
- if (code == Constants.ERROR_CODE_CANCELED) {
- cancel(true /* mayInterruptIfRunning */);
- return;
- }
- setException(convertErrorToException(code, message));
- }
- }
-
}
private Exception convertErrorToException(int code, String message) {
@@ -797,11 +631,12 @@ public class AccountManager {
return new AuthenticatorException(message);
}
- private class GetAuthTokenByTypeAndFeaturesTask extends AmsTask implements Future2Callback {
+ private class GetAuthTokenByTypeAndFeaturesTask
+ extends AmsTask implements AccountManagerCallback<Bundle> {
GetAuthTokenByTypeAndFeaturesTask(final String accountType, final String authTokenType,
final String[] features, Activity activityForPrompting,
final Bundle addAccountOptions, final Bundle loginOptions,
- Future2Callback callback, Handler handler) {
+ AccountManagerCallback<Bundle> callback, Handler handler) {
super(activityForPrompting, handler, callback);
if (accountType == null) throw new IllegalArgumentException("account type is null");
mAccountType = accountType;
@@ -811,101 +646,100 @@ public class AccountManager {
mLoginOptions = loginOptions;
mMyCallback = this;
}
- volatile Future2 mFuture = null;
+ volatile AccountManagerFuture<Bundle> mFuture = null;
final String mAccountType;
final String mAuthTokenType;
final String[] mFeatures;
final Bundle mAddAccountOptions;
final Bundle mLoginOptions;
- final Future2Callback mMyCallback;
+ final AccountManagerCallback<Bundle> mMyCallback;
public void doWork() throws RemoteException {
- getAccountsWithTypeAndFeatures(mAccountType, mFeatures, new Future2Callback() {
- public void run(Future2 future) {
- Bundle getAccountsResult;
- try {
- getAccountsResult = future.getResult();
- } catch (OperationCanceledException e) {
- setException(e);
- return;
- } catch (IOException e) {
- setException(e);
- return;
- } catch (AuthenticatorException e) {
- setException(e);
- return;
- }
-
- Parcelable[] accounts =
- getAccountsResult.getParcelableArray(Constants.ACCOUNTS_KEY);
- if (accounts.length == 0) {
- if (mActivity != null) {
- // no accounts, add one now. pretend that the user directly
- // made this request
- mFuture = addAccount(mAccountType, mAuthTokenType, mFeatures,
- mAddAccountOptions, mActivity, mMyCallback, mHandler);
- } else {
- // send result since we can't prompt to add an account
- Bundle result = new Bundle();
- result.putString(Constants.ACCOUNT_NAME_KEY, null);
- result.putString(Constants.ACCOUNT_TYPE_KEY, null);
- result.putString(Constants.AUTHTOKEN_KEY, null);
+ getAccountsByTypeAndFeatures(mAccountType, mFeatures,
+ new AccountManagerCallback<Account[]>() {
+ public void run(AccountManagerFuture<Account[]> future) {
+ Account[] accounts;
try {
- mResponse.onResult(result);
- } catch (RemoteException e) {
- // this will never happen
+ accounts = future.getResult();
+ } catch (OperationCanceledException e) {
+ setException(e);
+ return;
+ } catch (IOException e) {
+ setException(e);
+ return;
+ } catch (AuthenticatorException e) {
+ setException(e);
+ return;
}
- // we are done
- }
- } else if (accounts.length == 1) {
- // have a single account, return an authtoken for it
- if (mActivity == null) {
- mFuture = getAuthToken((Account) accounts[0], mAuthTokenType,
- false /* notifyAuthFailure */, mMyCallback, mHandler);
- } else {
- mFuture = getAuthToken((Account) accounts[0],
- mAuthTokenType, mLoginOptions,
- mActivity, mMyCallback, mHandler);
- }
- } else {
- if (mActivity != null) {
- IAccountManagerResponse chooseResponse =
- new IAccountManagerResponse.Stub() {
- public void onResult(Bundle value) throws RemoteException {
- Account account = new Account(
- value.getString(Constants.ACCOUNT_NAME_KEY),
- value.getString(Constants.ACCOUNT_TYPE_KEY));
- mFuture = getAuthToken(account, mAuthTokenType, mLoginOptions,
+
+ if (accounts.length == 0) {
+ if (mActivity != null) {
+ // no accounts, add one now. pretend that the user directly
+ // made this request
+ mFuture = addAccount(mAccountType, mAuthTokenType, mFeatures,
+ mAddAccountOptions, mActivity, mMyCallback, mHandler);
+ } else {
+ // send result since we can't prompt to add an account
+ Bundle result = new Bundle();
+ result.putString(Constants.ACCOUNT_NAME_KEY, null);
+ result.putString(Constants.ACCOUNT_TYPE_KEY, null);
+ result.putString(Constants.AUTHTOKEN_KEY, null);
+ try {
+ mResponse.onResult(result);
+ } catch (RemoteException e) {
+ // this will never happen
+ }
+ // we are done
+ }
+ } else if (accounts.length == 1) {
+ // have a single account, return an authtoken for it
+ if (mActivity == null) {
+ mFuture = getAuthToken(accounts[0], mAuthTokenType,
+ false /* notifyAuthFailure */, mMyCallback, mHandler);
+ } else {
+ mFuture = getAuthToken(accounts[0],
+ mAuthTokenType, mLoginOptions,
mActivity, mMyCallback, mHandler);
}
-
- public void onError(int errorCode, String errorMessage)
- throws RemoteException {
- mResponse.onError(errorCode, errorMessage);
+ } else {
+ if (mActivity != null) {
+ IAccountManagerResponse chooseResponse =
+ new IAccountManagerResponse.Stub() {
+ public void onResult(Bundle value) throws RemoteException {
+ Account account = new Account(
+ value.getString(Constants.ACCOUNT_NAME_KEY),
+ value.getString(Constants.ACCOUNT_TYPE_KEY));
+ mFuture = getAuthToken(account, mAuthTokenType, mLoginOptions,
+ mActivity, mMyCallback, mHandler);
+ }
+
+ public void onError(int errorCode, String errorMessage)
+ throws RemoteException {
+ mResponse.onError(errorCode, errorMessage);
+ }
+ };
+ // have many accounts, launch the chooser
+ Intent intent = new Intent();
+ intent.setClassName("android",
+ "android.accounts.ChooseAccountActivity");
+ intent.putExtra(Constants.ACCOUNTS_KEY, accounts);
+ intent.putExtra(Constants.ACCOUNT_MANAGER_RESPONSE_KEY,
+ new AccountManagerResponse(chooseResponse));
+ mActivity.startActivity(intent);
+ // the result will arrive via the IAccountManagerResponse
+ } else {
+ // send result since we can't prompt to select an account
+ Bundle result = new Bundle();
+ result.putString(Constants.ACCOUNTS_KEY, null);
+ try {
+ mResponse.onResult(result);
+ } catch (RemoteException e) {
+ // this will never happen
+ }
+ // we are done
}
- };
- // have many accounts, launch the chooser
- Intent intent = new Intent();
- intent.setClassName("android",
- "android.accounts.ChooseAccountActivity");
- intent.putExtra(Constants.ACCOUNTS_KEY, accounts);
- intent.putExtra(Constants.ACCOUNT_MANAGER_RESPONSE_KEY,
- new AccountManagerResponse(chooseResponse));
- mActivity.startActivity(intent);
- // the result will arrive via the IAccountManagerResponse
- } else {
- // send result since we can't prompt to select an account
- Bundle result = new Bundle();
- result.putString(Constants.ACCOUNTS_KEY, null);
- try {
- mResponse.onResult(result);
- } catch (RemoteException e) {
- // this will never happen
}
- // we are done
- }
- }
- }}, mHandler);
+ }}, mHandler);
}
@@ -915,7 +749,7 @@ public class AccountManager {
// or to cause this to be canceled if mFuture isn't set.
// Once this is done then getAuthTokenByFeatures can be changed to return a Future2.
- public void run(Future2 future) {
+ public void run(AccountManagerFuture<Bundle> future) {
try {
set(future.get());
} catch (InterruptedException e) {
@@ -932,7 +766,7 @@ public class AccountManager {
final String accountType, final String authTokenType, final String[] features,
final Activity activityForPrompting, final Bundle addAccountOptions,
final Bundle loginOptions,
- final Future2Callback callback, final Handler handler) {
+ final AccountManagerCallback<Bundle> callback, final Handler handler) {
if (accountType == null) throw new IllegalArgumentException("account type is null");
if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null");
new GetAuthTokenByTypeAndFeaturesTask(accountType, authTokenType, features,
@@ -942,13 +776,6 @@ public class AccountManager {
private final HashMap<OnAccountsUpdatedListener, Handler> mAccountsUpdatedListeners =
Maps.newHashMap();
- // These variable are only used from the LOGIN_ACCOUNTS_CHANGED_ACTION BroadcastReceiver
- // and its getAccounts() callback which are both invoked only on the main thread. As a
- // result we don't need to protect against concurrent accesses and any changes are guaranteed
- // to be visible when used. Basically, these two variables are thread-confined.
- private Future1<Account[]> mAccountsLookupFuture = null;
- private boolean mAccountLookupPending = false;
-
/**
* BroadcastReceiver that listens for the LOGIN_ACCOUNTS_CHANGED_ACTION intent
* so that it can read the updated list of accounts and send them to the listener
@@ -956,58 +783,14 @@ public class AccountManager {
*/
private final BroadcastReceiver mAccountsChangedBroadcastReceiver = new BroadcastReceiver() {
public void onReceive(final Context context, final Intent intent) {
- if (mAccountsLookupFuture != null) {
- // an accounts lookup is already in progress,
- // don't bother starting another request
- mAccountLookupPending = true;
- return;
- }
- // initiate a read of the accounts
- mAccountsLookupFuture = getAccounts(new Future1Callback<Account[]>() {
- public void run(Future1<Account[]> future) {
- // clear the future so that future receives will try the lookup again
- mAccountsLookupFuture = null;
-
- // get the accounts array
- Account[] accounts;
- try {
- accounts = future.getResult();
- } catch (OperationCanceledException e) {
- // this should never happen, but if it does pretend we got another
- // accounts changed broadcast
- if (Config.LOGD) {
- Log.d(TAG, "the accounts lookup for listener notifications was "
- + "canceled, try again by simulating the receipt of "
- + "a LOGIN_ACCOUNTS_CHANGED_ACTION broadcast");
- }
- onReceive(context, intent);
- return;
- }
-
- // send the result to the listeners
- synchronized (mAccountsUpdatedListeners) {
- for (Map.Entry<OnAccountsUpdatedListener, Handler> entry :
- mAccountsUpdatedListeners.entrySet()) {
- Account[] accountsCopy = new Account[accounts.length];
- // send the listeners a copy to make sure that one doesn't
- // change what another sees
- System.arraycopy(accounts, 0, accountsCopy, 0, accountsCopy.length);
- postToHandler(entry.getValue(), entry.getKey(), accountsCopy);
- }
- }
-
- // If mAccountLookupPending was set when the account lookup finished it
- // means that we had previously ignored a LOGIN_ACCOUNTS_CHANGED_ACTION
- // intent because a lookup was already in progress. Now that we are done
- // with this lookup and notification pretend that another intent
- // was received by calling onReceive() directly.
- if (mAccountLookupPending) {
- mAccountLookupPending = false;
- onReceive(context, intent);
- return;
- }
+ final Account[] accounts = getAccounts();
+ // send the result to the listeners
+ synchronized (mAccountsUpdatedListeners) {
+ for (Map.Entry<OnAccountsUpdatedListener, Handler> entry :
+ mAccountsUpdatedListeners.entrySet()) {
+ postToHandler(entry.getValue(), entry.getKey(), accounts);
}
- }, mMainHandler);
+ }
}
};
@@ -1045,15 +828,7 @@ public class AccountManager {
}
if (updateImmediately) {
- getAccounts(new Future1Callback<Account[]>() {
- public void run(Future1<Account[]> future) {
- try {
- listener.onAccountsUpdated(future.getResult());
- } catch (OperationCanceledException e) {
- // ignore
- }
- }
- }, handler);
+ postToHandler(handler, listener, getAccounts());
}
}
diff --git a/core/java/android/accounts/Future1Callback.java b/core/java/android/accounts/AccountManagerCallback.java
index 886671b..4aa7169 100644
--- a/core/java/android/accounts/Future1Callback.java
+++ b/core/java/android/accounts/AccountManagerCallback.java
@@ -15,6 +15,6 @@
*/
package android.accounts;
-public interface Future1Callback<V> {
- void run(Future1<V> future);
-}
+public interface AccountManagerCallback<V> {
+ void run(AccountManagerFuture<V> future);
+} \ No newline at end of file
diff --git a/core/java/android/accounts/AccountManagerFuture.java b/core/java/android/accounts/AccountManagerFuture.java
new file mode 100644
index 0000000..9939398
--- /dev/null
+++ b/core/java/android/accounts/AccountManagerFuture.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.accounts;
+
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeoutException;
+import java.io.IOException;
+
+/**
+ * An extension of {@link java.util.concurrent.Future} that provides wrappers for {@link #get()}
+ * that handle the various
+ * exceptions that {@link #get()} may return and rethrows them as exceptions specific to
+ * {@link android.accounts.AccountManager}.
+ */
+public interface AccountManagerFuture<V> extends Future<V> {
+ /**
+ * Wrapper for {@link java.util.concurrent.Future#get()}. If the get() throws
+ * {@link InterruptedException} then the
+ * {@link AccountManagerFuture} is canceled and
+ * {@link android.accounts.OperationCanceledException} is thrown.
+ * @return the {@link android.os.Bundle} that is returned by get()
+ * @throws android.accounts.OperationCanceledException if get() throws the unchecked
+ * CancellationException
+ * or if the Future was interrupted.
+ */
+ V getResult() throws OperationCanceledException, IOException, AuthenticatorException;
+
+ /**
+ * Wrapper for {@link java.util.concurrent.Future#get()}. If the get() throws
+ * {@link InterruptedException} then the
+ * {@link AccountManagerFuture} is canceled and
+ * {@link android.accounts.OperationCanceledException} is thrown.
+ * @param timeout the maximum time to wait
+ * @param unit the time unit of the timeout argument
+ * @return the {@link android.os.Bundle} that is returned by
+ * {@link java.util.concurrent.Future#get()}
+ * @throws android.accounts.OperationCanceledException if get() throws the unchecked
+ * {@link java.util.concurrent.CancellationException} or if the {@link AccountManagerFuture}
+ * was interrupted.
+ */
+ V getResult(long timeout, TimeUnit unit)
+ throws OperationCanceledException, IOException, AuthenticatorException;
+
+ @Deprecated
+ V get() throws InterruptedException, ExecutionException;
+
+ @Deprecated
+ V get(long timeout, TimeUnit unit)
+ throws InterruptedException, ExecutionException, TimeoutException;
+} \ No newline at end of file
diff --git a/core/java/android/accounts/AccountManagerService.java b/core/java/android/accounts/AccountManagerService.java
index 0c941be..140c814 100644
--- a/core/java/android/accounts/AccountManagerService.java
+++ b/core/java/android/accounts/AccountManagerService.java
@@ -214,50 +214,58 @@ public class AccountManagerService extends IAccountManager.Stub {
long identityToken = clearCallingIdentity();
try {
- SQLiteDatabase db = mOpenHelper.getReadableDatabase();
- Cursor cursor = db.query(TABLE_ACCOUNTS, new String[]{ACCOUNTS_PASSWORD},
- ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?",
- new String[]{account.mName, account.mType}, null, null, null);
- try {
- if (cursor.moveToNext()) {
- return cursor.getString(0);
- }
- return null;
- } finally {
- cursor.close();
- }
+ return readPasswordFromDatabase(account);
} finally {
restoreCallingIdentity(identityToken);
}
}
+ private String readPasswordFromDatabase(Account account) {
+ SQLiteDatabase db = mOpenHelper.getReadableDatabase();
+ Cursor cursor = db.query(TABLE_ACCOUNTS, new String[]{ACCOUNTS_PASSWORD},
+ ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?",
+ new String[]{account.name, account.type}, null, null, null);
+ try {
+ if (cursor.moveToNext()) {
+ return cursor.getString(0);
+ }
+ return null;
+ } finally {
+ cursor.close();
+ }
+ }
+
public String getUserData(Account account, String key) {
checkAuthenticateAccountsPermission(account);
long identityToken = clearCallingIdentity();
try {
- SQLiteDatabase db = mOpenHelper.getReadableDatabase();
- db.beginTransaction();
+ return readUserDataFromDatabase(account, key);
+ } finally {
+ restoreCallingIdentity(identityToken);
+ }
+ }
+
+ private String readUserDataFromDatabase(Account account, String key) {
+ SQLiteDatabase db = mOpenHelper.getReadableDatabase();
+ db.beginTransaction();
+ try {
+ long accountId = getAccountId(db, account);
+ if (accountId < 0) {
+ return null;
+ }
+ Cursor cursor = db.query(TABLE_EXTRAS, new String[]{EXTRAS_VALUE},
+ EXTRAS_ACCOUNTS_ID + "=" + accountId + " AND " + EXTRAS_KEY + "=?",
+ new String[]{key}, null, null, null);
try {
- long accountId = getAccountId(db, account);
- if (accountId < 0) {
- return null;
- }
- Cursor cursor = db.query(TABLE_EXTRAS, new String[]{EXTRAS_VALUE},
- EXTRAS_ACCOUNTS_ID + "=" + accountId + " AND " + EXTRAS_KEY + "=?",
- new String[]{key}, null, null, null);
- try {
- if (cursor.moveToNext()) {
- return cursor.getString(0);
- }
- return null;
- } finally {
- cursor.close();
+ if (cursor.moveToNext()) {
+ return cursor.getString(0);
}
+ return null;
} finally {
- db.endTransaction();
+ cursor.close();
}
} finally {
- restoreCallingIdentity(identityToken);
+ db.endTransaction();
}
}
@@ -280,39 +288,23 @@ public class AccountManagerService extends IAccountManager.Stub {
}
}
- public Account[] getAccounts() {
- checkReadAccountsPermission();
- long identityToken = clearCallingIdentity();
- try {
- return getAccountsByType(null);
- } finally {
- restoreCallingIdentity(identityToken);
- }
- }
-
public Account[] getAccountsByType(String accountType) {
- checkReadAccountsPermission();
- long identityToken = clearCallingIdentity();
- try {
- SQLiteDatabase db = mOpenHelper.getReadableDatabase();
+ SQLiteDatabase db = mOpenHelper.getReadableDatabase();
- final String selection = accountType == null ? null : (ACCOUNTS_TYPE + "=?");
- final String[] selectionArgs = accountType == null ? null : new String[]{accountType};
- Cursor cursor = db.query(TABLE_ACCOUNTS, ACCOUNT_NAME_TYPE_PROJECTION,
- selection, selectionArgs, null, null, null);
- try {
- int i = 0;
- Account[] accounts = new Account[cursor.getCount()];
- while (cursor.moveToNext()) {
- accounts[i] = new Account(cursor.getString(1), cursor.getString(2));
- i++;
- }
- return accounts;
- } finally {
- cursor.close();
+ final String selection = accountType == null ? null : (ACCOUNTS_TYPE + "=?");
+ final String[] selectionArgs = accountType == null ? null : new String[]{accountType};
+ Cursor cursor = db.query(TABLE_ACCOUNTS, ACCOUNT_NAME_TYPE_PROJECTION,
+ selection, selectionArgs, null, null, null);
+ try {
+ int i = 0;
+ Account[] accounts = new Account[cursor.getCount()];
+ while (cursor.moveToNext()) {
+ accounts[i] = new Account(cursor.getString(1), cursor.getString(2));
+ i++;
}
+ return accounts;
} finally {
- restoreCallingIdentity(identityToken);
+ cursor.close();
}
}
@@ -322,40 +314,44 @@ public class AccountManagerService extends IAccountManager.Stub {
// fails if the account already exists
long identityToken = clearCallingIdentity();
try {
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- db.beginTransaction();
- try {
- long numMatches = DatabaseUtils.longForQuery(db,
- "select count(*) from " + TABLE_ACCOUNTS
- + " WHERE " + ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?",
- new String[]{account.mName, account.mType});
- if (numMatches > 0) {
- return false;
- }
- ContentValues values = new ContentValues();
- values.put(ACCOUNTS_NAME, account.mName);
- values.put(ACCOUNTS_TYPE, account.mType);
- values.put(ACCOUNTS_PASSWORD, password);
- long accountId = db.insert(TABLE_ACCOUNTS, ACCOUNTS_NAME, values);
- if (accountId < 0) {
- return false;
- }
- if (extras != null) {
- for (String key : extras.keySet()) {
- final String value = extras.getString(key);
- if (insertExtra(db, accountId, key, value) < 0) {
- return false;
- }
+ return insertAccountIntoDatabase(account, password, extras);
+ } finally {
+ restoreCallingIdentity(identityToken);
+ }
+ }
+
+ private boolean insertAccountIntoDatabase(Account account, String password, Bundle extras) {
+ SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+ db.beginTransaction();
+ try {
+ long numMatches = DatabaseUtils.longForQuery(db,
+ "select count(*) from " + TABLE_ACCOUNTS
+ + " WHERE " + ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?",
+ new String[]{account.name, account.type});
+ if (numMatches > 0) {
+ return false;
+ }
+ ContentValues values = new ContentValues();
+ values.put(ACCOUNTS_NAME, account.name);
+ values.put(ACCOUNTS_TYPE, account.type);
+ values.put(ACCOUNTS_PASSWORD, password);
+ long accountId = db.insert(TABLE_ACCOUNTS, ACCOUNTS_NAME, values);
+ if (accountId < 0) {
+ return false;
+ }
+ if (extras != null) {
+ for (String key : extras.keySet()) {
+ final String value = extras.getString(key);
+ if (insertExtra(db, accountId, key, value) < 0) {
+ return false;
}
}
- db.setTransactionSuccessful();
- sendAccountsChangedBroadcast();
- return true;
- } finally {
- db.endTransaction();
}
+ db.setTransactionSuccessful();
+ sendAccountsChangedBroadcast();
+ return true;
} finally {
- restoreCallingIdentity(identityToken);
+ db.endTransaction();
}
}
@@ -367,19 +363,61 @@ public class AccountManagerService extends IAccountManager.Stub {
return db.insert(TABLE_EXTRAS, EXTRAS_KEY, values);
}
- public void removeAccount(Account account) {
+ public void removeAccount(IAccountManagerResponse response, Account account) {
checkManageAccountsPermission();
long identityToken = clearCallingIdentity();
try {
- final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- db.delete(TABLE_ACCOUNTS, ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?",
- new String[]{account.mName, account.mType});
- sendAccountsChangedBroadcast();
+ new RemoveAccountSession(response, account).bind();
} finally {
restoreCallingIdentity(identityToken);
}
}
+ private class RemoveAccountSession extends Session {
+ final Account mAccount;
+ public RemoveAccountSession(IAccountManagerResponse response, Account account) {
+ super(response, account.type, false /* expectActivityLaunch */);
+ mAccount = account;
+ }
+
+ protected String toDebugString(long now) {
+ return super.toDebugString(now) + ", removeAccount"
+ + ", account " + mAccount;
+ }
+
+ public void run() throws RemoteException {
+ mAuthenticator.getAccountRemovalAllowed(this, mAccount);
+ }
+
+ public void onResult(Bundle result) {
+ if (result != null && result.containsKey(Constants.BOOLEAN_RESULT_KEY)
+ && !result.containsKey(Constants.INTENT_KEY)) {
+ final boolean removalAllowed = result.getBoolean(Constants.BOOLEAN_RESULT_KEY);
+ if (removalAllowed) {
+ removeAccount(mAccount);
+ }
+ IAccountManagerResponse response = getResponseAndClose();
+ if (response != null) {
+ Bundle result2 = new Bundle();
+ result2.putBoolean(Constants.BOOLEAN_RESULT_KEY, removalAllowed);
+ try {
+ response.onResult(result2);
+ } catch (RemoteException e) {
+ // ignore
+ }
+ }
+ }
+ super.onResult(result);
+ }
+ }
+
+ private void removeAccount(Account account) {
+ final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+ db.delete(TABLE_ACCOUNTS, ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?",
+ new String[]{account.name, account.type});
+ sendAccountsChangedBroadcast();
+ }
+
public void invalidateAuthToken(String accountType, String authToken) {
checkManageAccountsPermission();
long identityToken = clearCallingIdentity();
@@ -398,6 +436,9 @@ public class AccountManagerService extends IAccountManager.Stub {
}
private void invalidateAuthToken(SQLiteDatabase db, String accountType, String authToken) {
+ if (authToken == null || accountType == null) {
+ return;
+ }
Cursor cursor = db.rawQuery(
"SELECT " + TABLE_AUTHTOKENS + "." + AUTHTOKENS_ID
+ ", " + TABLE_ACCOUNTS + "." + ACCOUNTS_NAME
@@ -488,7 +529,7 @@ public class AccountManagerService extends IAccountManager.Stub {
values.put(ACCOUNTS_PASSWORD, password);
mOpenHelper.getWritableDatabase().update(TABLE_ACCOUNTS, values,
ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?",
- new String[]{account.mName, account.mType});
+ new String[]{account.name, account.type});
sendAccountsChangedBroadcast();
} finally {
restoreCallingIdentity(identityToken);
@@ -509,37 +550,55 @@ public class AccountManagerService extends IAccountManager.Stub {
}
}
+ 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();
try {
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- db.beginTransaction();
- try {
- long accountId = getAccountId(db, account);
- if (accountId < 0) {
+ writeUserdataIntoDatabase(account, key, value);
+ } finally {
+ restoreCallingIdentity(identityToken);
+ }
+ }
+
+ private void writeUserdataIntoDatabase(Account account, String key, String value) {
+ SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+ db.beginTransaction();
+ try {
+ long accountId = getAccountId(db, account);
+ if (accountId < 0) {
+ return;
+ }
+ long extrasId = getExtrasId(db, accountId, key);
+ if (extrasId < 0 ) {
+ extrasId = insertExtra(db, accountId, key, value);
+ if (extrasId < 0) {
return;
}
- long extrasId = getExtrasId(db, accountId, key);
- if (extrasId < 0 ) {
- extrasId = insertExtra(db, accountId, key, value);
- if (extrasId < 0) {
- return;
- }
- } else {
- ContentValues values = new ContentValues();
- values.put(EXTRAS_VALUE, value);
- if (1 != db.update(TABLE_EXTRAS, values, EXTRAS_ID + "=" + extrasId, null)) {
- return;
- }
-
+ } else {
+ ContentValues values = new ContentValues();
+ values.put(EXTRAS_VALUE, value);
+ if (1 != db.update(TABLE_EXTRAS, values, EXTRAS_ID + "=" + extrasId, null)) {
+ return;
}
- db.setTransactionSuccessful();
- } finally {
- db.endTransaction();
+
}
+ db.setTransactionSuccessful();
} finally {
- restoreCallingIdentity(identityToken);
+ db.endTransaction();
}
}
@@ -571,14 +630,14 @@ public class AccountManagerService extends IAccountManager.Stub {
if (authToken != null) {
Bundle result = new Bundle();
result.putString(Constants.AUTHTOKEN_KEY, authToken);
- result.putString(Constants.ACCOUNT_NAME_KEY, account.mName);
- result.putString(Constants.ACCOUNT_TYPE_KEY, account.mType);
+ result.putString(Constants.ACCOUNT_NAME_KEY, account.name);
+ result.putString(Constants.ACCOUNT_TYPE_KEY, account.type);
onResult(response, result);
return;
}
}
- new Session(response, account.mType, expectActivityLaunch) {
+ new Session(response, account.type, expectActivityLaunch) {
protected String toDebugString(long now) {
if (loginOptions != null) loginOptions.keySet();
return super.toDebugString(now) + ", getAuthToken"
@@ -651,7 +710,7 @@ public class AccountManagerService extends IAccountManager.Stub {
mContext.getText(R.string.permission_request_notification_subtitle);
n.setLatestEventInfo(mContext,
mContext.getText(R.string.permission_request_notification_title),
- String.format(subtitleFormatString.toString(), account.mName),
+ String.format(subtitleFormatString.toString(), account.name),
PendingIntent.getActivity(mContext, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT));
((NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE))
.notify(getCredentialPermissionNotificationId(account, authTokenType, uid), n);
@@ -661,9 +720,9 @@ public class AccountManagerService extends IAccountManager.Stub {
AccountAuthenticatorResponse response, String authTokenType, String authTokenLabel) {
RegisteredServicesCache.ServiceInfo<AuthenticatorDescription> serviceInfo =
mAuthenticatorCache.getServiceInfo(
- AuthenticatorDescription.newKey(account.mType));
+ AuthenticatorDescription.newKey(account.type));
if (serviceInfo == null) {
- throw new IllegalArgumentException("unknown account type: " + account.mType);
+ throw new IllegalArgumentException("unknown account type: " + account.type);
}
final Context authContext;
@@ -671,7 +730,7 @@ public class AccountManagerService extends IAccountManager.Stub {
authContext = mContext.createPackageContext(
serviceInfo.type.packageName, 0);
} catch (PackageManager.NameNotFoundException e) {
- throw new IllegalArgumentException("unknown account type: " + account.mType);
+ throw new IllegalArgumentException("unknown account type: " + account.type);
}
Intent intent = new Intent(mContext, GrantCredentialsPermissionActivity.class);
@@ -750,7 +809,7 @@ public class AccountManagerService extends IAccountManager.Stub {
checkManageAccountsPermission();
long identityToken = clearCallingIdentity();
try {
- new Session(response, account.mType, expectActivityLaunch) {
+ new Session(response, account.type, expectActivityLaunch) {
public void run() throws RemoteException {
mAuthenticator.confirmCredentials(this, account);
}
@@ -769,7 +828,7 @@ public class AccountManagerService extends IAccountManager.Stub {
checkManageAccountsPermission();
long identityToken = clearCallingIdentity();
try {
- new Session(response, account.mType, false /* expectActivityLaunch */) {
+ new Session(response, account.type, false /* expectActivityLaunch */) {
public void run() throws RemoteException {
mAuthenticator.confirmPassword(this, account, password);
}
@@ -789,7 +848,7 @@ public class AccountManagerService extends IAccountManager.Stub {
checkManageAccountsPermission();
long identityToken = clearCallingIdentity();
try {
- new Session(response, account.mType, expectActivityLaunch) {
+ new Session(response, account.type, expectActivityLaunch) {
public void run() throws RemoteException {
mAuthenticator.updateCredentials(this, account, authTokenType, loginOptions);
}
@@ -898,10 +957,21 @@ public class AccountManagerService extends IAccountManager.Stub {
+ ", " + (mFeatures != null ? TextUtils.join(",", mFeatures) : null);
}
}
- public void getAccountsByTypeAndFeatures(IAccountManagerResponse response,
+
+ public Account[] getAccounts(String type) {
+ checkReadAccountsPermission();
+ long identityToken = clearCallingIdentity();
+ try {
+ return getAccountsByType(type);
+ } finally {
+ restoreCallingIdentity(identityToken);
+ }
+ }
+
+ public void getAccountsByFeatures(IAccountManagerResponse response,
String type, String[] features) {
checkReadAccountsPermission();
- if (type == null) {
+ if (features != null && type == null) {
if (response != null) {
try {
response.onError(Constants.ERROR_CODE_BAD_ARGUMENTS, "type is null");
@@ -913,6 +983,10 @@ public class AccountManagerService extends IAccountManager.Stub {
}
long identityToken = clearCallingIdentity();
try {
+ if (features == null || features.length == 0) {
+ getAccountsByType(type);
+ return;
+ }
new GetAccountsByTypeAndFeatureSession(response, type, features).bind();
} finally {
restoreCallingIdentity(identityToken);
@@ -925,7 +999,7 @@ public class AccountManagerService extends IAccountManager.Stub {
private long getAccountId(SQLiteDatabase db, Account account) {
Cursor cursor = db.query(TABLE_ACCOUNTS, new String[]{ACCOUNTS_ID},
- "name=? AND type=?", new String[]{account.mName, account.mType}, null, null, null);
+ "name=? AND type=?", new String[]{account.name, account.type}, null, null, null);
try {
if (cursor.moveToNext()) {
return cursor.getLong(0);
@@ -1401,7 +1475,7 @@ public class AccountManagerService extends IAccountManager.Stub {
}
private boolean permissionIsGranted(Account account, String authTokenType, int callerUid) {
- final boolean fromAuthenticator = hasAuthenticatorUid(account.mType, callerUid);
+ final boolean fromAuthenticator = hasAuthenticatorUid(account.type, callerUid);
final boolean hasExplicitGrants = hasExplicitlyGrantedPermission(account, authTokenType);
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "checkGrantsOrCallingUidAgainstAuthenticator: caller uid "
@@ -1416,7 +1490,9 @@ public class AccountManagerService extends IAccountManager.Stub {
for (RegisteredServicesCache.ServiceInfo<AuthenticatorDescription> serviceInfo :
mAuthenticatorCache.getAllServices()) {
if (serviceInfo.type.type.equals(accountType)) {
- return serviceInfo.uid == callingUid;
+ return (serviceInfo.uid == callingUid) ||
+ (mContext.getPackageManager().checkSignatures(serviceInfo.uid, callingUid)
+ == PackageManager.SIGNATURE_MATCH);
}
}
return false;
@@ -1428,7 +1504,7 @@ public class AccountManagerService extends IAccountManager.Stub {
}
SQLiteDatabase db = mOpenHelper.getReadableDatabase();
String[] args = {String.valueOf(Binder.getCallingUid()), authTokenType,
- account.mName, account.mType};
+ account.name, account.type};
final boolean permissionGranted =
DatabaseUtils.longForQuery(db, COUNT_OF_MATCHING_GRANTS, args) != 0;
if (!permissionGranted && isDebuggableMonkeyBuild) {
@@ -1444,7 +1520,7 @@ public class AccountManagerService extends IAccountManager.Stub {
private void checkCallingUidAgainstAuthenticator(Account account) {
final int uid = Binder.getCallingUid();
- if (!hasAuthenticatorUid(account.mType, uid)) {
+ if (!hasAuthenticatorUid(account.type, uid)) {
String msg = "caller uid " + uid + " is different than the authenticator's uid";
Log.w(TAG, msg);
throw new SecurityException(msg);
diff --git a/core/java/android/accounts/ChooseAccountActivity.java b/core/java/android/accounts/ChooseAccountActivity.java
index 83377f3..bd6f205 100644
--- a/core/java/android/accounts/ChooseAccountActivity.java
+++ b/core/java/android/accounts/ChooseAccountActivity.java
@@ -45,7 +45,7 @@ public class ChooseAccountActivity extends ListActivity {
String[] mAccountNames = new String[mAccounts.length];
for (int i = 0; i < mAccounts.length; i++) {
- mAccountNames[i] = ((Account) mAccounts[i]).mName;
+ mAccountNames[i] = ((Account) mAccounts[i]).name;
}
// Use an existing ListAdapter that will map an array
@@ -59,8 +59,8 @@ public class ChooseAccountActivity extends ListActivity {
Account account = (Account) mAccounts[position];
Log.d(TAG, "selected account " + account);
Bundle bundle = new Bundle();
- bundle.putString(Constants.ACCOUNT_NAME_KEY, account.mName);
- bundle.putString(Constants.ACCOUNT_TYPE_KEY, account.mType);
+ bundle.putString(Constants.ACCOUNT_NAME_KEY, account.name);
+ bundle.putString(Constants.ACCOUNT_TYPE_KEY, account.type);
mResult = bundle;
finish();
}
diff --git a/core/java/android/accounts/Constants.java b/core/java/android/accounts/Constants.java
index da8173f..8736f41 100644
--- a/core/java/android/accounts/Constants.java
+++ b/core/java/android/accounts/Constants.java
@@ -31,6 +31,7 @@ public class Constants {
public static final String AUTHENTICATOR_TYPES_KEY = "authenticator_types";
public static final String USERDATA_KEY = "userdata";
public static final String AUTHTOKEN_KEY = "authtoken";
+ public static final String PASSWORD_KEY = "password";
public static final String ACCOUNT_NAME_KEY = "authAccount";
public static final String ACCOUNT_TYPE_KEY = "accountType";
public static final String ERROR_CODE_KEY = "errorCode";
diff --git a/core/java/android/accounts/Future1.java b/core/java/android/accounts/Future1.java
deleted file mode 100644
index 386cb6e..0000000
--- a/core/java/android/accounts/Future1.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.accounts;
-
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-
-/**
- * An extension of {@link Future} that provides wrappers for {@link #get()} that handle the various
- * exceptions that {@link #get()} may return and rethrows them as exceptions specific to
- * {@link AccountManager}.
- */
-public interface Future1<V> extends Future<V> {
- /**
- * Wrapper for {@link Future#get()}. If the get() throws {@link InterruptedException} then the
- * {@link Future1} is canceled and {@link OperationCanceledException} is thrown.
- * @return the {@link android.os.Bundle} that is returned by get()
- * @throws OperationCanceledException if get() throws the unchecked CancellationException
- * or if the Future was interrupted.
- */
- V getResult() throws OperationCanceledException;
-
- /**
- * Wrapper for {@link Future#get()}. If the get() throws {@link InterruptedException} then the
- * {@link Future1} is canceled and {@link OperationCanceledException} is thrown.
- * @param timeout the maximum time to wait
- * @param unit the time unit of the timeout argument
- * @return the {@link android.os.Bundle} that is returned by {@link Future#get()}
- * @throws OperationCanceledException if get() throws the unchecked
- * {@link java.util.concurrent.CancellationException} or if the {@link Future1} was interrupted.
- */
- V getResult(long timeout, TimeUnit unit) throws OperationCanceledException;
-} \ No newline at end of file
diff --git a/core/java/android/accounts/Future2.java b/core/java/android/accounts/Future2.java
deleted file mode 100644
index b2ea84f..0000000
--- a/core/java/android/accounts/Future2.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.accounts;
-
-import android.os.Bundle;
-
-import java.io.IOException;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-
-/**
- * An extension of {@link Future} that provides wrappers for {@link #get()} that handle the various
- * exceptions that {@link #get()} may return and rethrows them as exceptions specific to
- * {@link AccountManager}.
- */
-public interface Future2 extends Future<Bundle> {
- /**
- * Wrapper for {@link Future#get()}. If the get() throws {@link InterruptedException} then the
- * {@link Future2} is canceled and {@link OperationCanceledException} is thrown.
- * @return the {@link android.os.Bundle} that is returned by {@link Future#get()}
- * @throws OperationCanceledException if get() throws the unchecked
- * {@link java.util.concurrent.CancellationException} or if the {@link Future2} was interrupted.
- * @throws IOException if the request was unable to complete due to a network error
- * @throws AuthenticatorException if there was an error communicating with the
- * {@link AbstractAccountAuthenticator}.
- */
- Bundle getResult()
- throws OperationCanceledException, IOException, AuthenticatorException;
-
- /**
- * Wrapper for {@link Future#get()}. If the get() throws {@link InterruptedException} then the
- * {@link Future2} is canceled and {@link OperationCanceledException} is thrown.
- * @param timeout the maximum time to wait
- * @param unit the time unit of the timeout argument
- * @return the {@link android.os.Bundle} that is returned by {@link Future#get()}
- * @throws OperationCanceledException if get() throws the unchecked
- * {@link java.util.concurrent.CancellationException} or if the {@link Future2} was interrupted.
- * @throws IOException if the request was unable to complete due to a network error
- * @throws AuthenticatorException if there was an error communicating with the
- * {@link AbstractAccountAuthenticator}.
- */
- Bundle getResult(long timeout, TimeUnit unit)
- throws OperationCanceledException, IOException, AuthenticatorException;
-}
diff --git a/core/java/android/accounts/Future2Callback.java b/core/java/android/accounts/Future2Callback.java
deleted file mode 100644
index 7ef0c94..0000000
--- a/core/java/android/accounts/Future2Callback.java
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.accounts;
-
-public interface Future2Callback {
- void run(Future2 future);
-} \ No newline at end of file
diff --git a/core/java/android/accounts/GrantCredentialsPermissionActivity.java b/core/java/android/accounts/GrantCredentialsPermissionActivity.java
index f92d43f..e06afb4 100644
--- a/core/java/android/accounts/GrantCredentialsPermissionActivity.java
+++ b/core/java/android/accounts/GrantCredentialsPermissionActivity.java
@@ -63,12 +63,12 @@ public class GrantCredentialsPermissionActivity extends Activity implements View
CharSequence grantCredentialsPermissionFormat = getResources().getText(
R.string.grant_credentials_permission_message_desc);
messageView.setText(String.format(grantCredentialsPermissionFormat.toString(),
- mAccount.mName, accountTypeLabel));
+ mAccount.name, accountTypeLabel));
} else {
CharSequence grantCredentialsPermissionFormat = getResources().getText(
R.string.grant_credentials_permission_message_with_authtokenlabel_desc);
messageView.setText(String.format(grantCredentialsPermissionFormat.toString(),
- authTokenLabel, mAccount.mName, accountTypeLabel));
+ authTokenLabel, mAccount.name, accountTypeLabel));
}
String[] packageLabels = new String[packages.length];
diff --git a/core/java/android/accounts/IAccountAuthenticator.aidl b/core/java/android/accounts/IAccountAuthenticator.aidl
index 7d4de39..48f053c 100644
--- a/core/java/android/accounts/IAccountAuthenticator.aidl
+++ b/core/java/android/accounts/IAccountAuthenticator.aidl
@@ -70,4 +70,9 @@ oneway interface IAccountAuthenticator {
*/
void hasFeatures(in IAccountAuthenticatorResponse response, in Account account,
in String[] features);
+
+ /**
+ * Gets whether or not the account is allowed to be removed.
+ */
+ void getAccountRemovalAllowed(in IAccountAuthenticatorResponse response, in Account account);
}
diff --git a/core/java/android/accounts/IAccountManager.aidl b/core/java/android/accounts/IAccountManager.aidl
index 15ab4e8..411952b 100644
--- a/core/java/android/accounts/IAccountManager.aidl
+++ b/core/java/android/accounts/IAccountManager.aidl
@@ -21,6 +21,7 @@ import android.accounts.Account;
import android.accounts.AuthenticatorDescription;
import android.os.Bundle;
+
/**
* Central application service that provides account management.
* @hide
@@ -29,10 +30,10 @@ interface IAccountManager {
String getPassword(in Account account);
String getUserData(in Account account, String key);
AuthenticatorDescription[] getAuthenticatorTypes();
- Account[] getAccounts();
- Account[] getAccountsByType(String accountType);
+ Account[] getAccounts(String accountType);
+ void getAccountsByFeatures(in IAccountManagerResponse response, String accountType, in String[] features);
boolean addAccount(in Account account, String password, in Bundle extras);
- void removeAccount(in Account account);
+ void removeAccount(in IAccountManagerResponse response, in Account account);
void invalidateAuthToken(String accountType, String authToken);
String peekAuthToken(in Account account, String authTokenType);
void setAuthToken(in Account account, String authTokenType, String authToken);
@@ -52,8 +53,6 @@ interface IAccountManager {
boolean expectActivityLaunch);
void confirmCredentials(in IAccountManagerResponse response, in Account account,
boolean expectActivityLaunch);
- void getAccountsByTypeAndFeatures(in IAccountManagerResponse response, String accountType,
- in String[] features);
/*
* @deprecated
diff --git a/core/java/android/content/AbstractSyncableContentProvider.java b/core/java/android/content/AbstractSyncableContentProvider.java
index 218f501..808f30c 100644
--- a/core/java/android/content/AbstractSyncableContentProvider.java
+++ b/core/java/android/content/AbstractSyncableContentProvider.java
@@ -170,7 +170,7 @@ public abstract class AbstractSyncableContentProvider extends SyncableContentPro
// AbstractGDataSyncAdapter, which will put acore into a crash loop
ArrayList<Account> gaiaAccounts = new ArrayList<Account>();
for (Account acct: accounts) {
- if (acct.mType.equals("com.google.GAIA")) {
+ if (acct.type.equals("com.google.GAIA")) {
gaiaAccounts.add(acct);
}
}
@@ -693,7 +693,7 @@ public abstract class AbstractSyncableContentProvider extends SyncableContentPro
if (!accounts.containsKey(account)) {
int numDeleted;
numDeleted = db.delete(table, "_sync_account=? AND _sync_account_type=?",
- new String[]{account.mName, account.mType});
+ new String[]{account.name, account.type});
if (Config.LOGV) {
Log.v(TAG, "deleted " + numDeleted
+ " records from table " + table
@@ -726,7 +726,7 @@ public abstract class AbstractSyncableContentProvider extends SyncableContentPro
// remove the data in the synced tables
for (String table : tables) {
db.delete(table, SYNC_ACCOUNT_WHERE_CLAUSE,
- new String[]{account.mName, account.mType});
+ new String[]{account.name, account.type});
}
db.setTransactionSuccessful();
} finally {
diff --git a/core/java/android/content/AbstractTableMerger.java b/core/java/android/content/AbstractTableMerger.java
index a3daa01..9545fd7 100644
--- a/core/java/android/content/AbstractTableMerger.java
+++ b/core/java/android/content/AbstractTableMerger.java
@@ -174,7 +174,7 @@ public abstract class AbstractTableMerger
Cursor diffsCursor = null;
try {
// load the local database entries, so we can merge them with the server
- final String[] accountSelectionArgs = new String[]{account.mName, account.mType};
+ final String[] accountSelectionArgs = new String[]{account.name, account.type};
localCursor = mDb.query(mTable, syncDirtyProjection,
SELECT_MARKED, accountSelectionArgs, null, null,
mTable + "." + _SYNC_ID);
@@ -487,7 +487,7 @@ public abstract class AbstractTableMerger
try {
if (deleteBySyncId) {
selectionArgs = new String[]{diffsCursor.getString(serverSyncIdColumn),
- account.mName, account.mType};
+ account.name, account.type};
c = mDb.query(mTable, new String[]{BaseColumns._ID}, SELECT_BY_SYNC_ID_AND_ACCOUNT,
selectionArgs, null, null, null);
} else {
@@ -534,7 +534,7 @@ public abstract class AbstractTableMerger
SyncableContentProvider clientDiffs = mergeResult.tempContentProvider;
if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "generating client updates");
- final String[] accountSelectionArgs = new String[]{account.mName, account.mType};
+ final String[] accountSelectionArgs = new String[]{account.name, account.type};
// Generate the client updates and insertions
// Create a cursor for dirty records
diff --git a/core/java/android/content/SyncManager.java b/core/java/android/content/SyncManager.java
index d54e260..f256394 100644
--- a/core/java/android/content/SyncManager.java
+++ b/core/java/android/content/SyncManager.java
@@ -596,7 +596,7 @@ class SyncManager implements OnAccountsUpdatedListener {
for (String authority : syncableAuthorities) {
for (Account account : accounts) {
- if (mSyncAdapters.getServiceInfo(new SyncAdapterType(authority, account.mType))
+ if (mSyncAdapters.getServiceInfo(new SyncAdapterType(authority, account.type))
!= null) {
scheduleSyncOperation(
new SyncOperation(account, source, authority, extras, delay));
@@ -1094,8 +1094,8 @@ class SyncManager implements OnAccountsUpdatedListener {
for (int i=0; i<N; i++) {
SyncStorageEngine.PendingOperation op = ops.get(i);
pw.print(" #"); pw.print(i); pw.print(": account=");
- pw.print(op.account.mName); pw.print(":");
- pw.print(op.account.mType); pw.print(" authority=");
+ pw.print(op.account.name); pw.print(":");
+ pw.print(op.account.type); pw.print(" authority=");
pw.println(op.authority);
if (op.extras != null && op.extras.size() > 0) {
sb.setLength(0);
@@ -1125,8 +1125,8 @@ class SyncManager implements OnAccountsUpdatedListener {
processedAccounts.add(curAccount);
- pw.print(" Account "); pw.print(authority.account.mName);
- pw.print(" "); pw.print(authority.account.mType);
+ pw.print(" Account "); pw.print(authority.account.name);
+ pw.print(" "); pw.print(authority.account.type);
pw.println(":");
for (int j=i; j<N; j++) {
status = statuses.get(j);
@@ -1248,9 +1248,9 @@ class SyncManager implements OnAccountsUpdatedListener {
= mSyncStorageEngine.getAuthority(item.authorityId);
pw.print(" #"); pw.print(i+1); pw.print(": ");
if (authority != null) {
- pw.print(authority.account.mName);
+ pw.print(authority.account.name);
pw.print(":");
- pw.print(authority.account.mType);
+ pw.print(authority.account.type);
pw.print(" ");
pw.print(authority.authority);
} else {
@@ -1636,7 +1636,7 @@ class SyncManager implements OnAccountsUpdatedListener {
// connect to the sync adapter
SyncAdapterType syncAdapterType = new SyncAdapterType(op.authority,
- op.account.mType);
+ op.account.type);
RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapterInfo =
mSyncAdapters.getServiceInfo(syncAdapterType);
if (syncAdapterInfo == null) {
diff --git a/core/java/android/content/SyncStateContentProviderHelper.java b/core/java/android/content/SyncStateContentProviderHelper.java
index dc728ec..64bbe25 100644
--- a/core/java/android/content/SyncStateContentProviderHelper.java
+++ b/core/java/android/content/SyncStateContentProviderHelper.java
@@ -172,7 +172,7 @@ public class SyncStateContentProviderHelper {
*/
public void copySyncState(SQLiteDatabase dbSrc, SQLiteDatabase dbDest,
Account account) {
- final String[] whereArgs = new String[]{account.mName, account.mType};
+ final String[] whereArgs = new String[]{account.name, account.type};
Cursor c = dbSrc.query(SYNC_STATE_TABLE,
new String[]{"_sync_account", "_sync_account_type", "data"},
ACCOUNT_WHERE, whereArgs, null, null, null);
@@ -209,7 +209,7 @@ public class SyncStateContentProviderHelper {
public void discardSyncData(SQLiteDatabase db, Account account) {
if (account != null) {
- db.delete(SYNC_STATE_TABLE, ACCOUNT_WHERE, new String[]{account.mName, account.mType});
+ db.delete(SYNC_STATE_TABLE, ACCOUNT_WHERE, new String[]{account.name, account.type});
} else {
db.delete(SYNC_STATE_TABLE, null, null);
}
@@ -220,7 +220,7 @@ public class SyncStateContentProviderHelper {
*/
public byte[] readSyncDataBytes(SQLiteDatabase db, Account account) {
Cursor c = db.query(SYNC_STATE_TABLE, null, ACCOUNT_WHERE,
- new String[]{account.mName, account.mType}, null, null, null);
+ new String[]{account.name, account.type}, null, null, null);
try {
if (c.moveToFirst()) {
return c.getBlob(c.getColumnIndexOrThrow("data"));
@@ -238,6 +238,6 @@ public class SyncStateContentProviderHelper {
ContentValues values = new ContentValues();
values.put("data", data);
db.update(SYNC_STATE_TABLE, values, ACCOUNT_WHERE,
- new String[]{account.mName, account.mType});
+ new String[]{account.name, account.type});
}
}
diff --git a/core/java/android/content/SyncStorageEngine.java b/core/java/android/content/SyncStorageEngine.java
index 8cc0642..b3f9bbb 100644
--- a/core/java/android/content/SyncStorageEngine.java
+++ b/core/java/android/content/SyncStorageEngine.java
@@ -1127,8 +1127,8 @@ public class SyncStorageEngine extends Handler {
AuthorityInfo authority = mAuthorities.get(i);
out.startTag(null, "authority");
out.attribute(null, "id", Integer.toString(authority.ident));
- out.attribute(null, "account", authority.account.mName);
- out.attribute(null, "type", authority.account.mType);
+ out.attribute(null, "account", authority.account.name);
+ out.attribute(null, "type", authority.account.type);
out.attribute(null, "authority", authority.authority);
if (!authority.enabled) {
out.attribute(null, "enabled", "false");
diff --git a/core/java/android/provider/Calendar.java b/core/java/android/provider/Calendar.java
index 489d936..fab3f3d 100644
--- a/core/java/android/provider/Calendar.java
+++ b/core/java/android/provider/Calendar.java
@@ -174,7 +174,7 @@ public final class Calendar {
return Calendar.Calendars.delete(cr,
Calendar.Calendars._SYNC_ACCOUNT + "=? AND "
+ Calendar.Calendars._SYNC_ACCOUNT_TYPE + "=?",
- new String[] {account.mName, account.mType});
+ new String[] {account.name, account.type});
}
/**
diff --git a/core/java/android/provider/SubscribedFeeds.java b/core/java/android/provider/SubscribedFeeds.java
index f94b442..8e9f402 100644
--- a/core/java/android/provider/SubscribedFeeds.java
+++ b/core/java/android/provider/SubscribedFeeds.java
@@ -119,8 +119,8 @@ public class SubscribedFeeds {
String authority, String service) {
ContentValues values = new ContentValues();
values.put(SubscribedFeeds.Feeds.FEED, feed);
- values.put(SubscribedFeeds.Feeds._SYNC_ACCOUNT, account.mName);
- values.put(SubscribedFeeds.Feeds._SYNC_ACCOUNT_TYPE, account.mType);
+ values.put(SubscribedFeeds.Feeds._SYNC_ACCOUNT, account.name);
+ values.put(SubscribedFeeds.Feeds._SYNC_ACCOUNT_TYPE, account.type);
values.put(SubscribedFeeds.Feeds.AUTHORITY, authority);
values.put(SubscribedFeeds.Feeds.SERVICE, service);
return resolver.insert(SubscribedFeeds.Feeds.CONTENT_URI, values);
@@ -134,7 +134,7 @@ public class SubscribedFeeds {
where.append(" AND " + SubscribedFeeds.Feeds.FEED + "=?");
where.append(" AND " + SubscribedFeeds.Feeds.AUTHORITY + "=?");
return resolver.delete(SubscribedFeeds.Feeds.CONTENT_URI,
- where.toString(), new String[] {account.mName, account.mType, feed, authority});
+ where.toString(), new String[] {account.name, account.type, feed, authority});
}
public static int deleteFeeds(ContentResolver resolver,
@@ -144,7 +144,7 @@ public class SubscribedFeeds {
where.append(" AND " + SubscribedFeeds.Feeds._SYNC_ACCOUNT_TYPE + "=?");
where.append(" AND " + SubscribedFeeds.Feeds.AUTHORITY + "=?");
return resolver.delete(SubscribedFeeds.Feeds.CONTENT_URI,
- where.toString(), new String[] {account.mName, account.mType, authority});
+ where.toString(), new String[] {account.name, account.type, authority});
}
/**
diff --git a/core/java/android/provider/SyncStateContract.java b/core/java/android/provider/SyncStateContract.java
index 7927e28..5c93af0 100644
--- a/core/java/android/provider/SyncStateContract.java
+++ b/core/java/android/provider/SyncStateContract.java
@@ -71,7 +71,7 @@ public class SyncStateContract {
public static byte[] get(ContentProviderClient provider, Uri uri,
Account account) throws RemoteException {
Cursor c = provider.query(uri, DATA_PROJECTION, SELECT_BY_ACCOUNT,
- new String[]{account.mName, account.mType}, null);
+ new String[]{account.name, account.type}, null);
try {
if (c.moveToNext()) {
return c.getBlob(c.getColumnIndexOrThrow(Columns.DATA));
@@ -96,8 +96,8 @@ public class SyncStateContract {
Account account, byte[] data) throws RemoteException {
ContentValues values = new ContentValues();
values.put(Columns.DATA, data);
- values.put(Columns.ACCOUNT_NAME, account.mName);
- values.put(Columns.ACCOUNT_TYPE, account.mType);
+ values.put(Columns.ACCOUNT_NAME, account.name);
+ values.put(Columns.ACCOUNT_TYPE, account.type);
provider.insert(uri, values);
}
@@ -116,8 +116,8 @@ public class SyncStateContract {
values.put(Columns.DATA, data);
return ContentProviderOperation
.newInsert(uri)
- .withValue(Columns.ACCOUNT_NAME, account.mName)
- .withValue(Columns.ACCOUNT_TYPE, account.mType)
+ .withValue(Columns.ACCOUNT_NAME, account.name)
+ .withValue(Columns.ACCOUNT_TYPE, account.type)
.withValues(values)
.build();
}