diff options
author | Fred Quintana <fredq@google.com> | 2009-08-15 21:45:26 -0700 |
---|---|---|
committer | Fred Quintana <fredq@google.com> | 2009-08-15 22:40:25 -0700 |
commit | ffd0cb04f97e62d286d185c520580d81a9c328b1 (patch) | |
tree | d864589d0cfa54abc971091b172d1497cb79adcb /core/java/android | |
parent | fa2944d93f4c5050fb4a99d90006791c2995b31c (diff) | |
download | frameworks_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')
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(); } |