Merge "[RemoveAccount API]: Adding support for intent." into lmp-mr1-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
fdcdb7429e
@@ -2708,7 +2708,9 @@ package android.accounts {
|
||||
method public void invalidateAuthToken(java.lang.String, java.lang.String);
|
||||
method public static android.content.Intent newChooseAccountIntent(android.accounts.Account, java.util.ArrayList<android.accounts.Account>, java.lang.String[], boolean, java.lang.String, java.lang.String, java.lang.String[], android.os.Bundle);
|
||||
method public java.lang.String peekAuthToken(android.accounts.Account, java.lang.String);
|
||||
method public android.accounts.AccountManagerFuture<java.lang.Boolean> removeAccount(android.accounts.Account, android.accounts.AccountManagerCallback<java.lang.Boolean>, android.os.Handler);
|
||||
method public deprecated android.accounts.AccountManagerFuture<java.lang.Boolean> removeAccount(android.accounts.Account, android.accounts.AccountManagerCallback<java.lang.Boolean>, android.os.Handler);
|
||||
method public android.accounts.AccountManagerFuture<android.os.Bundle> removeAccount(android.accounts.Account, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
|
||||
method public boolean removeAccountExplicitly(android.accounts.Account);
|
||||
method public void removeOnAccountsUpdatedListener(android.accounts.OnAccountsUpdateListener);
|
||||
method public android.accounts.AccountManagerFuture<android.accounts.Account> renameAccount(android.accounts.Account, java.lang.String, android.accounts.AccountManagerCallback<android.accounts.Account>, android.os.Handler);
|
||||
method public void setAuthToken(android.accounts.Account, java.lang.String, java.lang.String);
|
||||
|
||||
@@ -17,37 +17,37 @@
|
||||
package android.accounts;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.res.Resources;
|
||||
import android.database.SQLException;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.RemoteException;
|
||||
import android.os.Parcelable;
|
||||
import android.os.Build;
|
||||
import android.os.Process;
|
||||
import android.os.RemoteException;
|
||||
import android.os.UserHandle;
|
||||
import android.util.Log;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.R;
|
||||
import com.google.android.collect.Maps;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.FutureTask;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.android.internal.R;
|
||||
import com.google.android.collect.Maps;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
/**
|
||||
* This class provides access to a centralized registry of the user's
|
||||
@@ -747,13 +747,17 @@ public class AccountManager {
|
||||
* null for the main thread
|
||||
* @return An {@link AccountManagerFuture} which resolves to a Boolean,
|
||||
* true if the account has been successfully removed
|
||||
* @deprecated use
|
||||
* {@link #removeAccount(Account, Activity, AccountManagerCallback, Handler)}
|
||||
* instead
|
||||
*/
|
||||
@Deprecated
|
||||
public AccountManagerFuture<Boolean> removeAccount(final Account account,
|
||||
AccountManagerCallback<Boolean> callback, Handler handler) {
|
||||
if (account == null) throw new IllegalArgumentException("account is null");
|
||||
return new Future2Task<Boolean>(handler, callback) {
|
||||
public void doWork() throws RemoteException {
|
||||
mService.removeAccount(mResponse, account);
|
||||
mService.removeAccount(mResponse, account, false);
|
||||
}
|
||||
public Boolean bundleToResult(Bundle bundle) throws AuthenticatorException {
|
||||
if (!bundle.containsKey(KEY_BOOLEAN_RESULT)) {
|
||||
@@ -764,10 +768,61 @@ public class AccountManager {
|
||||
}.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an account from the AccountManager. Does nothing if the account
|
||||
* does not exist. Does not delete the account from the server.
|
||||
* The authenticator may have its own policies preventing account
|
||||
* deletion, in which case the account will not be deleted.
|
||||
*
|
||||
* <p>This method may be called from any thread, but the returned
|
||||
* {@link AccountManagerFuture} must not be used on the main thread.
|
||||
*
|
||||
* <p>This method requires the caller to hold the permission
|
||||
* {@link android.Manifest.permission#MANAGE_ACCOUNTS}.
|
||||
*
|
||||
* @param account The {@link Account} to remove
|
||||
* @param activity The {@link Activity} context to use for launching a new
|
||||
* authenticator-defined sub-Activity to prompt the user to delete an
|
||||
* account; used only to call startActivity(); if null, the prompt
|
||||
* will not be launched directly, but the {@link Intent} may be
|
||||
* returned to the caller instead
|
||||
* @param callback Callback to invoke when the request completes,
|
||||
* null for no callback
|
||||
* @param handler {@link Handler} identifying the callback thread,
|
||||
* null for the main thread
|
||||
* @return An {@link AccountManagerFuture} which resolves to a Bundle with
|
||||
* {@link #KEY_BOOLEAN_RESULT} if activity was specified and an account
|
||||
* was removed or if active. If no activity was specified, the returned
|
||||
* Bundle contains only {@link #KEY_INTENT} with the {@link Intent}
|
||||
* needed to launch the actual account removal process, if authenticator
|
||||
* needs the activity launch. If an error occurred,
|
||||
* {@link AccountManagerFuture#getResult()} throws:
|
||||
* <ul>
|
||||
* <li> {@link AuthenticatorException} if no authenticator was registered for
|
||||
* this account type or the authenticator failed to respond
|
||||
* <li> {@link OperationCanceledException} if the operation was canceled for
|
||||
* any reason, including the user canceling the creation process or
|
||||
* adding accounts (of this type) has been disabled by policy
|
||||
* </ul>
|
||||
*/
|
||||
public AccountManagerFuture<Bundle> removeAccount(final Account account,
|
||||
final Activity activity, AccountManagerCallback<Bundle> callback, Handler handler) {
|
||||
if (account == null) throw new IllegalArgumentException("account is null");
|
||||
return new AmsTask(activity, handler, callback) {
|
||||
public void doWork() throws RemoteException {
|
||||
mService.removeAccount(mResponse, account, activity != null);
|
||||
}
|
||||
}.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #removeAccount(Account, AccountManagerCallback, Handler)
|
||||
* @hide
|
||||
* @deprecated use
|
||||
* {@link #removeAccountAsUser(Account, Activity, AccountManagerCallback, Handler)}
|
||||
* instead
|
||||
*/
|
||||
@Deprecated
|
||||
public AccountManagerFuture<Boolean> removeAccountAsUser(final Account account,
|
||||
AccountManagerCallback<Boolean> callback, Handler handler,
|
||||
final UserHandle userHandle) {
|
||||
@@ -775,7 +830,7 @@ public class AccountManager {
|
||||
if (userHandle == null) throw new IllegalArgumentException("userHandle is null");
|
||||
return new Future2Task<Boolean>(handler, callback) {
|
||||
public void doWork() throws RemoteException {
|
||||
mService.removeAccountAsUser(mResponse, account, userHandle.getIdentifier());
|
||||
mService.removeAccountAsUser(mResponse, account, false, userHandle.getIdentifier());
|
||||
}
|
||||
public Boolean bundleToResult(Bundle bundle) throws AuthenticatorException {
|
||||
if (!bundle.containsKey(KEY_BOOLEAN_RESULT)) {
|
||||
@@ -786,6 +841,52 @@ public class AccountManager {
|
||||
}.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #removeAccount(Account, Activity, AccountManagerCallback, Handler)
|
||||
* @hide
|
||||
*/
|
||||
public AccountManagerFuture<Bundle> removeAccountAsUser(final Account account,
|
||||
final Activity activity, AccountManagerCallback<Bundle> callback, Handler handler,
|
||||
final UserHandle userHandle) {
|
||||
if (account == null)
|
||||
throw new IllegalArgumentException("account is null");
|
||||
if (userHandle == null)
|
||||
throw new IllegalArgumentException("userHandle is null");
|
||||
return new AmsTask(activity, handler, callback) {
|
||||
public void doWork() throws RemoteException {
|
||||
mService.removeAccountAsUser(mResponse, account, activity != null,
|
||||
userHandle.getIdentifier());
|
||||
}
|
||||
}.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an account directly. Normally used by authenticators, not
|
||||
* directly by applications. Does not delete the account from the server.
|
||||
* The authenticator may have its own policies preventing account deletion,
|
||||
* in which case the account will not be deleted.
|
||||
* <p>
|
||||
* It is safe to call this method from the main thread.
|
||||
* <p>
|
||||
* This method requires the caller to hold the permission
|
||||
* {@link android.Manifest.permission#AUTHENTICATE_ACCOUNTS} and to have the
|
||||
* same UID or signature as the account's authenticator.
|
||||
*
|
||||
* @param account The {@link Account} to delete.
|
||||
* @return True if the account was successfully deleted, false if the
|
||||
* account did not exist, the account is null, or another error
|
||||
* occurs.
|
||||
*/
|
||||
public boolean removeAccountExplicitly(Account account) {
|
||||
if (account == null) throw new IllegalArgumentException("account is null");
|
||||
try {
|
||||
return mService.removeAccountExplicitly(account);
|
||||
} catch (RemoteException e) {
|
||||
// won't ever happen
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an auth token from the AccountManager's cache. Does nothing if
|
||||
* the auth token is not currently in the cache. Applications must call this
|
||||
|
||||
@@ -37,8 +37,11 @@ interface IAccountManager {
|
||||
void hasFeatures(in IAccountManagerResponse response, in Account account, in String[] features);
|
||||
void getAccountsByFeatures(in IAccountManagerResponse response, String accountType, in String[] features);
|
||||
boolean addAccountExplicitly(in Account account, String password, in Bundle extras);
|
||||
void removeAccount(in IAccountManagerResponse response, in Account account);
|
||||
void removeAccountAsUser(in IAccountManagerResponse response, in Account account, int userId);
|
||||
void removeAccount(in IAccountManagerResponse response, in Account account,
|
||||
boolean expectActivityLaunch);
|
||||
void removeAccountAsUser(in IAccountManagerResponse response, in Account account,
|
||||
boolean expectActivityLaunch, int userId);
|
||||
boolean removeAccountExplicitly(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);
|
||||
|
||||
@@ -77,7 +77,6 @@ import com.android.internal.R;
|
||||
import com.android.internal.util.ArrayUtils;
|
||||
import com.android.internal.util.IndentingPrintWriter;
|
||||
import com.android.server.FgThread;
|
||||
|
||||
import com.google.android.collect.Lists;
|
||||
import com.google.android.collect.Sets;
|
||||
|
||||
@@ -1043,7 +1042,8 @@ public class AccountManagerService
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAccount(IAccountManagerResponse response, Account account) {
|
||||
public void removeAccount(IAccountManagerResponse response, Account account,
|
||||
boolean expectActivityLaunch) {
|
||||
if (Log.isLoggable(TAG, Log.VERBOSE)) {
|
||||
Log.v(TAG, "removeAccount: " + account
|
||||
+ ", response " + response
|
||||
@@ -1088,7 +1088,7 @@ public class AccountManagerService
|
||||
}
|
||||
|
||||
try {
|
||||
new RemoveAccountSession(accounts, response, account).bind();
|
||||
new RemoveAccountSession(accounts, response, account, expectActivityLaunch).bind();
|
||||
} finally {
|
||||
restoreCallingIdentity(identityToken);
|
||||
}
|
||||
@@ -1096,7 +1096,7 @@ public class AccountManagerService
|
||||
|
||||
@Override
|
||||
public void removeAccountAsUser(IAccountManagerResponse response, Account account,
|
||||
int userId) {
|
||||
boolean expectActivityLaunch, int userId) {
|
||||
if (Log.isLoggable(TAG, Log.VERBOSE)) {
|
||||
Log.v(TAG, "removeAccount: " + account
|
||||
+ ", response " + response
|
||||
@@ -1145,7 +1145,30 @@ public class AccountManagerService
|
||||
}
|
||||
|
||||
try {
|
||||
new RemoveAccountSession(accounts, response, account).bind();
|
||||
new RemoveAccountSession(accounts, response, account, expectActivityLaunch).bind();
|
||||
} finally {
|
||||
restoreCallingIdentity(identityToken);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeAccountExplicitly(Account account) {
|
||||
if (Log.isLoggable(TAG, Log.VERBOSE)) {
|
||||
Log.v(TAG, "removeAccountExplicitly: " + account
|
||||
+ ", caller's uid " + Binder.getCallingUid()
|
||||
+ ", pid " + Binder.getCallingPid());
|
||||
}
|
||||
if (account == null) throw new IllegalArgumentException("account is null");
|
||||
checkAuthenticateAccountsPermission(account);
|
||||
|
||||
UserAccounts accounts = getUserAccountsForCaller();
|
||||
int userId = Binder.getCallingUserHandle().getIdentifier();
|
||||
if (!canUserModifyAccounts(userId) || !canUserModifyAccountsForType(userId, account.type)) {
|
||||
return false;
|
||||
}
|
||||
long identityToken = clearCallingIdentity();
|
||||
try {
|
||||
return removeAccountInternal(accounts, account);
|
||||
} finally {
|
||||
restoreCallingIdentity(identityToken);
|
||||
}
|
||||
@@ -1154,8 +1177,8 @@ public class AccountManagerService
|
||||
private class RemoveAccountSession extends Session {
|
||||
final Account mAccount;
|
||||
public RemoveAccountSession(UserAccounts accounts, IAccountManagerResponse response,
|
||||
Account account) {
|
||||
super(accounts, response, account.type, false /* expectActivityLaunch */,
|
||||
Account account, boolean expectActivityLaunch) {
|
||||
super(accounts, response, account.type, expectActivityLaunch,
|
||||
true /* stripAuthTokenFromResult */);
|
||||
mAccount = account;
|
||||
}
|
||||
@@ -1203,10 +1226,12 @@ public class AccountManagerService
|
||||
removeAccountInternal(getUserAccountsForCaller(), account);
|
||||
}
|
||||
|
||||
private void removeAccountInternal(UserAccounts accounts, Account account) {
|
||||
private boolean removeAccountInternal(UserAccounts accounts, Account account) {
|
||||
int deleted;
|
||||
synchronized (accounts.cacheLock) {
|
||||
final SQLiteDatabase db = accounts.openHelper.getWritableDatabase();
|
||||
db.delete(TABLE_ACCOUNTS, ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?",
|
||||
deleted = db.delete(TABLE_ACCOUNTS, ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE
|
||||
+ "=?",
|
||||
new String[]{account.name, account.type});
|
||||
removeAccountFromCacheLocked(accounts, account);
|
||||
sendAccountsChangedBroadcast(accounts.userId);
|
||||
@@ -1226,6 +1251,7 @@ public class AccountManagerService
|
||||
Binder.restoreCallingIdentity(id);
|
||||
}
|
||||
}
|
||||
return (deleted > 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user