Loading api/current.txt +2 −0 Original line number Diff line number Diff line Loading @@ -2736,6 +2736,7 @@ package android.accounts { } public class AccountManager { method public boolean accountAuthenticated(android.accounts.Account); method public android.accounts.AccountManagerFuture<android.os.Bundle> addAccount(java.lang.String, java.lang.String, java.lang.String[], android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler); method public boolean addAccountExplicitly(android.accounts.Account, java.lang.String, android.os.Bundle); method public void addOnAccountsUpdatedListener(android.accounts.OnAccountsUpdateListener, android.os.Handler, boolean); Loading Loading @@ -2796,6 +2797,7 @@ package android.accounts { field public static final java.lang.String KEY_ERROR_CODE = "errorCode"; field public static final java.lang.String KEY_ERROR_MESSAGE = "errorMessage"; field public static final java.lang.String KEY_INTENT = "intent"; field public static final java.lang.String KEY_LAST_AUTHENTICATE_TIME_MILLIS_EPOCH = "lastAuthenticatedTimeMillisEpoch"; field public static final java.lang.String KEY_PASSWORD = "password"; field public static final java.lang.String KEY_USERDATA = "userdata"; field public static final java.lang.String LOGIN_ACCOUNTS_CHANGED_ACTION = "android.accounts.LOGIN_ACCOUNTS_CHANGED"; api/system-current.txt +2 −0 Original line number Diff line number Diff line Loading @@ -2815,6 +2815,7 @@ package android.accounts { } public class AccountManager { method public boolean accountAuthenticated(android.accounts.Account); method public android.accounts.AccountManagerFuture<android.os.Bundle> addAccount(java.lang.String, java.lang.String, java.lang.String[], android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler); method public boolean addAccountExplicitly(android.accounts.Account, java.lang.String, android.os.Bundle); method public void addOnAccountsUpdatedListener(android.accounts.OnAccountsUpdateListener, android.os.Handler, boolean); Loading Loading @@ -2875,6 +2876,7 @@ package android.accounts { field public static final java.lang.String KEY_ERROR_CODE = "errorCode"; field public static final java.lang.String KEY_ERROR_MESSAGE = "errorMessage"; field public static final java.lang.String KEY_INTENT = "intent"; field public static final java.lang.String KEY_LAST_AUTHENTICATE_TIME_MILLIS_EPOCH = "lastAuthenticatedTimeMillisEpoch"; field public static final java.lang.String KEY_PASSWORD = "password"; field public static final java.lang.String KEY_USERDATA = "userdata"; field public static final java.lang.String LOGIN_ACCOUNTS_CHANGED_ACTION = "android.accounts.LOGIN_ACCOUNTS_CHANGED"; core/java/android/accounts/AccountManager.java +44 −6 Original line number Diff line number Diff line Loading @@ -202,6 +202,14 @@ public class AccountManager { public static final String KEY_ERROR_MESSAGE = "errorMessage"; public static final String KEY_USERDATA = "userdata"; /** * Bundle key used to supply the last time the credentials of the account * were authenticated successfully. Time is specified in milliseconds since * epoch. */ public static final String KEY_LAST_AUTHENTICATE_TIME_MILLIS_EPOCH = "lastAuthenticatedTimeMillisEpoch"; /** * Authenticators using 'customTokens' option will also get the UID of the * caller Loading Loading @@ -662,6 +670,31 @@ public class AccountManager { } } /** * Informs the system that the account has been authenticated recently. This * recency may be used by other applications to verify the account. This * should be called only when the user has entered correct credentials for * the account. * <p> * It is not safe to call this method from the main thread. As such, call it * from another thread. * <p> * This method requires the caller to hold the permission * {@link android.Manifest.permission#AUTHENTICATE_ACCOUNTS} and should be * called from the account's authenticator. * * @param account The {@link Account} to be updated. */ public boolean accountAuthenticated(Account account) { if (account == null) throw new IllegalArgumentException("account is null"); try { return mService.accountAuthenticated(account); } catch (RemoteException e) { throw new RuntimeException(e); } } /** * Rename the specified {@link Account}. This is equivalent to removing * the existing account and adding a new renamed account with the old Loading Loading @@ -1544,15 +1577,20 @@ public class AccountManager { * with these fields if activity or password was supplied and * the account was successfully verified: * <ul> * <li> {@link #KEY_ACCOUNT_NAME} - the name of the account created * <li> {@link #KEY_ACCOUNT_NAME} - the name of the account verified * <li> {@link #KEY_ACCOUNT_TYPE} - the type of the account * <li> {@link #KEY_BOOLEAN_RESULT} - true to indicate success * </ul> * * If no activity or password was specified, the returned Bundle contains * only {@link #KEY_INTENT} with the {@link Intent} needed to launch the * password prompt. If an error occurred, * {@link AccountManagerFuture#getResult()} throws: * {@link #KEY_INTENT} with the {@link Intent} needed to launch the * password prompt. * * <p>Also the returning Bundle may contain {@link * #KEY_LAST_AUTHENTICATE_TIME_MILLIS_EPOCH} indicating the last time the * credential was validated/created. * * If an error occurred,{@link AccountManagerFuture#getResult()} throws: * <ul> * <li> {@link AuthenticatorException} if the authenticator failed to respond * <li> {@link OperationCanceledException} if the operation was canceled for Loading Loading @@ -1625,7 +1663,7 @@ public class AccountManager { * <li> {@link #KEY_ACCOUNT_TYPE} - the type of the account * </ul> * * If no activity was specified, the returned Bundle contains only * If no activity was specified, the returned Bundle contains * {@link #KEY_INTENT} with the {@link Intent} needed to launch the * password prompt. If an error occurred, * {@link AccountManagerFuture#getResult()} throws: Loading core/java/android/accounts/IAccountManager.aidl +1 −0 Original line number Diff line number Diff line Loading @@ -67,6 +67,7 @@ interface IAccountManager { boolean expectActivityLaunch); void confirmCredentialsAsUser(in IAccountManagerResponse response, in Account account, in Bundle options, boolean expectActivityLaunch, int userId); boolean accountAuthenticated(in Account account); void getAuthTokenLabel(in IAccountManagerResponse response, String accountType, String authTokenType); Loading services/core/java/com/android/server/accounts/AccountManagerService.java +95 −15 Original line number Diff line number Diff line Loading @@ -109,7 +109,7 @@ public class AccountManagerService private static final int TIMEOUT_DELAY_MS = 1000 * 60; private static final String DATABASE_NAME = "accounts.db"; private static final int DATABASE_VERSION = 6; private static final int DATABASE_VERSION = 7; private final Context mContext; Loading @@ -131,6 +131,8 @@ public class AccountManagerService private static final String ACCOUNTS_TYPE_COUNT = "count(type)"; private static final String ACCOUNTS_PASSWORD = "password"; private static final String ACCOUNTS_PREVIOUS_NAME = "previous_name"; private static final String ACCOUNTS_LAST_AUTHENTICATE_TIME_EPOCH_MILLIS = "last_password_entry_time_millis_epoch"; private static final String TABLE_AUTHTOKENS = "authtokens"; private static final String AUTHTOKENS_ID = "_id"; Loading Loading @@ -697,7 +699,8 @@ public class AccountManagerService long identityToken = clearCallingIdentity(); try { new Session(fromAccounts, response, account.type, false, false /* stripAuthTokenFromResult */) { false /* stripAuthTokenFromResult */, account.name, false /* authDetailsRequired */) { @Override protected String toDebugString(long now) { return super.toDebugString(now) + ", getAccountCredentialsForClone" Loading Loading @@ -725,12 +728,43 @@ public class AccountManagerService } } @Override public boolean accountAuthenticated(final Account account) { if (account == null) { throw new IllegalArgumentException("account is null"); } checkAuthenticateAccountsPermission(account); final UserAccounts accounts = getUserAccountsForCaller(); int userId = Binder.getCallingUserHandle().getIdentifier(); if (!canUserModifyAccounts(userId) || !canUserModifyAccountsForType(userId, account.type)) { return false; } synchronized (accounts.cacheLock) { final ContentValues values = new ContentValues(); values.put(ACCOUNTS_LAST_AUTHENTICATE_TIME_EPOCH_MILLIS, System.currentTimeMillis()); final SQLiteDatabase db = accounts.openHelper.getWritableDatabase(); int i = db.update( TABLE_ACCOUNTS, values, ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE + "=?", new String[] { account.name, account.type }); if (i > 0) { return true; } } return false; } private void completeCloningAccount(IAccountManagerResponse response, final Bundle accountCredentials, final Account account, final UserAccounts targetUser) { long id = clearCallingIdentity(); try { new Session(targetUser, response, account.type, false, false /* stripAuthTokenFromResult */) { false /* stripAuthTokenFromResult */, account.name, false /* authDetailsRequired */) { @Override protected String toDebugString(long now) { return super.toDebugString(now) + ", getAccountCredentialsForClone" Loading Loading @@ -795,6 +829,7 @@ public class AccountManagerService values.put(ACCOUNTS_NAME, account.name); values.put(ACCOUNTS_TYPE, account.type); values.put(ACCOUNTS_PASSWORD, password); values.put(ACCOUNTS_LAST_AUTHENTICATE_TIME_EPOCH_MILLIS, System.currentTimeMillis()); long accountId = db.insert(TABLE_ACCOUNTS, ACCOUNTS_NAME, values); if (accountId < 0) { Log.w(TAG, "insertAccountIntoDatabase: " + account Loading Loading @@ -885,7 +920,8 @@ public class AccountManagerService public TestFeaturesSession(UserAccounts accounts, IAccountManagerResponse response, Account account, String[] features) { super(accounts, response, account.type, false /* expectActivityLaunch */, true /* stripAuthTokenFromResult */); true /* stripAuthTokenFromResult */, account.name, false /* authDetailsRequired */); mFeatures = features; mAccount = account; } Loading Loading @@ -1184,7 +1220,8 @@ public class AccountManagerService public RemoveAccountSession(UserAccounts accounts, IAccountManagerResponse response, Account account, boolean expectActivityLaunch) { super(accounts, response, account.type, expectActivityLaunch, true /* stripAuthTokenFromResult */); true /* stripAuthTokenFromResult */, account.name, false /* authDetailsRequired */); mAccount = account; } Loading Loading @@ -1419,6 +1456,13 @@ public class AccountManagerService try { final ContentValues values = new ContentValues(); values.put(ACCOUNTS_PASSWORD, password); long time = 0; // Only set current time, if it is a valid password. For clear password case, it // should not be set. if (password != null) { time = System.currentTimeMillis(); } values.put(ACCOUNTS_LAST_AUTHENTICATE_TIME_EPOCH_MILLIS, time); final long accountId = getAccountIdLocked(db, account); if (accountId >= 0) { final String[] argsAccountId = {String.valueOf(accountId)}; Loading Loading @@ -1547,8 +1591,9 @@ public class AccountManagerService UserAccounts accounts = getUserAccounts(UserHandle.getUserId(callingUid)); long identityToken = clearCallingIdentity(); try { new Session(accounts, response, accountType, false, false /* stripAuthTokenFromResult */) { new Session(accounts, response, accountType, false /* expectActivityLaunch */, false /* stripAuthTokenFromResult */, null /* accountName */, false /* authDetailsRequired */) { @Override protected String toDebugString(long now) { return super.toDebugString(now) + ", getAuthTokenLabel" Loading Loading @@ -1648,7 +1693,8 @@ public class AccountManagerService } new Session(accounts, response, account.type, expectActivityLaunch, false /* stripAuthTokenFromResult */) { false /* stripAuthTokenFromResult */, account.name, false /* authDetailsRequired */) { @Override protected String toDebugString(long now) { if (loginOptions != null) loginOptions.keySet(); Loading Loading @@ -1842,7 +1888,8 @@ public class AccountManagerService long identityToken = clearCallingIdentity(); try { new Session(accounts, response, accountType, expectActivityLaunch, true /* stripAuthTokenFromResult */) { true /* stripAuthTokenFromResult */, null /* accountName */, false /* authDetailsRequired */) { @Override public void run() throws RemoteException { mAuthenticator.addAccount(this, mAccountType, authTokenType, requiredFeatures, Loading Loading @@ -1917,7 +1964,8 @@ public class AccountManagerService long identityToken = clearCallingIdentity(); try { new Session(accounts, response, accountType, expectActivityLaunch, true /* stripAuthTokenFromResult */) { true /* stripAuthTokenFromResult */, null /* accountName */, false /* authDetailsRequired */) { @Override public void run() throws RemoteException { mAuthenticator.addAccount(this, mAccountType, authTokenType, requiredFeatures, Loading Loading @@ -1973,7 +2021,8 @@ public class AccountManagerService long identityToken = clearCallingIdentity(); try { new Session(accounts, response, account.type, expectActivityLaunch, true /* stripAuthTokenFromResult */) { true /* stripAuthTokenFromResult */, account.name, true /* authDetailsRequired */) { @Override public void run() throws RemoteException { mAuthenticator.confirmCredentials(this, account, options); Loading Loading @@ -2009,7 +2058,8 @@ public class AccountManagerService long identityToken = clearCallingIdentity(); try { new Session(accounts, response, account.type, expectActivityLaunch, true /* stripAuthTokenFromResult */) { true /* stripAuthTokenFromResult */, account.name, false /* authDetailsRequired */) { @Override public void run() throws RemoteException { mAuthenticator.updateCredentials(this, account, authTokenType, loginOptions); Loading Loading @@ -2045,7 +2095,8 @@ public class AccountManagerService long identityToken = clearCallingIdentity(); try { new Session(accounts, response, accountType, expectActivityLaunch, true /* stripAuthTokenFromResult */) { true /* stripAuthTokenFromResult */, null /* accountName */, false /* authDetailsRequired */) { @Override public void run() throws RemoteException { mAuthenticator.editProperties(this, mAccountType); Loading @@ -2071,7 +2122,8 @@ public class AccountManagerService public GetAccountsByTypeAndFeatureSession(UserAccounts accounts, IAccountManagerResponse response, String type, String[] features, int callingUid) { super(accounts, response, type, false /* expectActivityLaunch */, true /* stripAuthTokenFromResult */); true /* stripAuthTokenFromResult */, null /* accountName */, false /* authDetailsRequired */); mCallingUid = callingUid; mFeatures = features; } Loading Loading @@ -2437,6 +2489,9 @@ public class AccountManagerService final String mAccountType; final boolean mExpectActivityLaunch; final long mCreationTime; final String mAccountName; // Indicates if we need to add auth details(like last credential time) final boolean mAuthDetailsRequired; public int mNumResults = 0; private int mNumRequestContinued = 0; Loading @@ -2448,7 +2503,8 @@ public class AccountManagerService protected final UserAccounts mAccounts; public Session(UserAccounts accounts, IAccountManagerResponse response, String accountType, boolean expectActivityLaunch, boolean stripAuthTokenFromResult) { boolean expectActivityLaunch, boolean stripAuthTokenFromResult, String accountName, boolean authDetailsRequired) { super(); //if (response == null) throw new IllegalArgumentException("response is null"); if (accountType == null) throw new IllegalArgumentException("accountType is null"); Loading @@ -2458,6 +2514,9 @@ public class AccountManagerService mAccountType = accountType; mExpectActivityLaunch = expectActivityLaunch; mCreationTime = SystemClock.elapsedRealtime(); mAccountName = accountName; mAuthDetailsRequired = authDetailsRequired; synchronized (mSessions) { mSessions.put(toString(), this); } Loading Loading @@ -2592,6 +2651,16 @@ public class AccountManagerService public void onResult(Bundle result) { mNumResults++; Intent intent = null; if (result != null && mAuthDetailsRequired) { long lastAuthenticatedTime = DatabaseUtils.longForQuery( mAccounts.openHelper.getReadableDatabase(), "select " + ACCOUNTS_LAST_AUTHENTICATE_TIME_EPOCH_MILLIS + " from " + TABLE_ACCOUNTS + " WHERE " + ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE + "=?", new String[]{mAccountName, mAccountType}); result.putLong(AccountManager.KEY_LAST_AUTHENTICATE_TIME_MILLIS_EPOCH, lastAuthenticatedTime); } if (result != null && (intent = result.getParcelable(AccountManager.KEY_INTENT)) != null) { /* Loading Loading @@ -2798,6 +2867,7 @@ public class AccountManagerService + ACCOUNTS_TYPE + " TEXT NOT NULL, " + ACCOUNTS_PASSWORD + " TEXT, " + ACCOUNTS_PREVIOUS_NAME + " TEXT, " + ACCOUNTS_LAST_AUTHENTICATE_TIME_EPOCH_MILLIS + " INTEGER DEFAULT 0, " + "UNIQUE(" + ACCOUNTS_NAME + "," + ACCOUNTS_TYPE + "))"); db.execSQL("CREATE TABLE " + TABLE_AUTHTOKENS + " ( " Loading Loading @@ -2833,6 +2903,11 @@ public class AccountManagerService + "UNIQUE(" + ACCOUNTS_NAME + "," + ACCOUNTS_TYPE + "))"); } private void addLastSuccessfullAuthenticatedTimeColumn(SQLiteDatabase db) { db.execSQL("ALTER TABLE " + TABLE_ACCOUNTS + " ADD COLUMN " + ACCOUNTS_LAST_AUTHENTICATE_TIME_EPOCH_MILLIS + " DEFAULT 0"); } private void addOldAccountNameColumn(SQLiteDatabase db) { db.execSQL("ALTER TABLE " + TABLE_ACCOUNTS + " ADD COLUMN " + ACCOUNTS_PREVIOUS_NAME); } Loading Loading @@ -2892,6 +2967,11 @@ public class AccountManagerService oldVersion++; } if (oldVersion == 6) { addLastSuccessfullAuthenticatedTimeColumn(db); oldVersion++; } if (oldVersion != newVersion) { Log.e(TAG, "failed to upgrade version " + oldVersion + " to version " + newVersion); } Loading Loading
api/current.txt +2 −0 Original line number Diff line number Diff line Loading @@ -2736,6 +2736,7 @@ package android.accounts { } public class AccountManager { method public boolean accountAuthenticated(android.accounts.Account); method public android.accounts.AccountManagerFuture<android.os.Bundle> addAccount(java.lang.String, java.lang.String, java.lang.String[], android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler); method public boolean addAccountExplicitly(android.accounts.Account, java.lang.String, android.os.Bundle); method public void addOnAccountsUpdatedListener(android.accounts.OnAccountsUpdateListener, android.os.Handler, boolean); Loading Loading @@ -2796,6 +2797,7 @@ package android.accounts { field public static final java.lang.String KEY_ERROR_CODE = "errorCode"; field public static final java.lang.String KEY_ERROR_MESSAGE = "errorMessage"; field public static final java.lang.String KEY_INTENT = "intent"; field public static final java.lang.String KEY_LAST_AUTHENTICATE_TIME_MILLIS_EPOCH = "lastAuthenticatedTimeMillisEpoch"; field public static final java.lang.String KEY_PASSWORD = "password"; field public static final java.lang.String KEY_USERDATA = "userdata"; field public static final java.lang.String LOGIN_ACCOUNTS_CHANGED_ACTION = "android.accounts.LOGIN_ACCOUNTS_CHANGED";
api/system-current.txt +2 −0 Original line number Diff line number Diff line Loading @@ -2815,6 +2815,7 @@ package android.accounts { } public class AccountManager { method public boolean accountAuthenticated(android.accounts.Account); method public android.accounts.AccountManagerFuture<android.os.Bundle> addAccount(java.lang.String, java.lang.String, java.lang.String[], android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler); method public boolean addAccountExplicitly(android.accounts.Account, java.lang.String, android.os.Bundle); method public void addOnAccountsUpdatedListener(android.accounts.OnAccountsUpdateListener, android.os.Handler, boolean); Loading Loading @@ -2875,6 +2876,7 @@ package android.accounts { field public static final java.lang.String KEY_ERROR_CODE = "errorCode"; field public static final java.lang.String KEY_ERROR_MESSAGE = "errorMessage"; field public static final java.lang.String KEY_INTENT = "intent"; field public static final java.lang.String KEY_LAST_AUTHENTICATE_TIME_MILLIS_EPOCH = "lastAuthenticatedTimeMillisEpoch"; field public static final java.lang.String KEY_PASSWORD = "password"; field public static final java.lang.String KEY_USERDATA = "userdata"; field public static final java.lang.String LOGIN_ACCOUNTS_CHANGED_ACTION = "android.accounts.LOGIN_ACCOUNTS_CHANGED";
core/java/android/accounts/AccountManager.java +44 −6 Original line number Diff line number Diff line Loading @@ -202,6 +202,14 @@ public class AccountManager { public static final String KEY_ERROR_MESSAGE = "errorMessage"; public static final String KEY_USERDATA = "userdata"; /** * Bundle key used to supply the last time the credentials of the account * were authenticated successfully. Time is specified in milliseconds since * epoch. */ public static final String KEY_LAST_AUTHENTICATE_TIME_MILLIS_EPOCH = "lastAuthenticatedTimeMillisEpoch"; /** * Authenticators using 'customTokens' option will also get the UID of the * caller Loading Loading @@ -662,6 +670,31 @@ public class AccountManager { } } /** * Informs the system that the account has been authenticated recently. This * recency may be used by other applications to verify the account. This * should be called only when the user has entered correct credentials for * the account. * <p> * It is not safe to call this method from the main thread. As such, call it * from another thread. * <p> * This method requires the caller to hold the permission * {@link android.Manifest.permission#AUTHENTICATE_ACCOUNTS} and should be * called from the account's authenticator. * * @param account The {@link Account} to be updated. */ public boolean accountAuthenticated(Account account) { if (account == null) throw new IllegalArgumentException("account is null"); try { return mService.accountAuthenticated(account); } catch (RemoteException e) { throw new RuntimeException(e); } } /** * Rename the specified {@link Account}. This is equivalent to removing * the existing account and adding a new renamed account with the old Loading Loading @@ -1544,15 +1577,20 @@ public class AccountManager { * with these fields if activity or password was supplied and * the account was successfully verified: * <ul> * <li> {@link #KEY_ACCOUNT_NAME} - the name of the account created * <li> {@link #KEY_ACCOUNT_NAME} - the name of the account verified * <li> {@link #KEY_ACCOUNT_TYPE} - the type of the account * <li> {@link #KEY_BOOLEAN_RESULT} - true to indicate success * </ul> * * If no activity or password was specified, the returned Bundle contains * only {@link #KEY_INTENT} with the {@link Intent} needed to launch the * password prompt. If an error occurred, * {@link AccountManagerFuture#getResult()} throws: * {@link #KEY_INTENT} with the {@link Intent} needed to launch the * password prompt. * * <p>Also the returning Bundle may contain {@link * #KEY_LAST_AUTHENTICATE_TIME_MILLIS_EPOCH} indicating the last time the * credential was validated/created. * * If an error occurred,{@link AccountManagerFuture#getResult()} throws: * <ul> * <li> {@link AuthenticatorException} if the authenticator failed to respond * <li> {@link OperationCanceledException} if the operation was canceled for Loading Loading @@ -1625,7 +1663,7 @@ public class AccountManager { * <li> {@link #KEY_ACCOUNT_TYPE} - the type of the account * </ul> * * If no activity was specified, the returned Bundle contains only * If no activity was specified, the returned Bundle contains * {@link #KEY_INTENT} with the {@link Intent} needed to launch the * password prompt. If an error occurred, * {@link AccountManagerFuture#getResult()} throws: Loading
core/java/android/accounts/IAccountManager.aidl +1 −0 Original line number Diff line number Diff line Loading @@ -67,6 +67,7 @@ interface IAccountManager { boolean expectActivityLaunch); void confirmCredentialsAsUser(in IAccountManagerResponse response, in Account account, in Bundle options, boolean expectActivityLaunch, int userId); boolean accountAuthenticated(in Account account); void getAuthTokenLabel(in IAccountManagerResponse response, String accountType, String authTokenType); Loading
services/core/java/com/android/server/accounts/AccountManagerService.java +95 −15 Original line number Diff line number Diff line Loading @@ -109,7 +109,7 @@ public class AccountManagerService private static final int TIMEOUT_DELAY_MS = 1000 * 60; private static final String DATABASE_NAME = "accounts.db"; private static final int DATABASE_VERSION = 6; private static final int DATABASE_VERSION = 7; private final Context mContext; Loading @@ -131,6 +131,8 @@ public class AccountManagerService private static final String ACCOUNTS_TYPE_COUNT = "count(type)"; private static final String ACCOUNTS_PASSWORD = "password"; private static final String ACCOUNTS_PREVIOUS_NAME = "previous_name"; private static final String ACCOUNTS_LAST_AUTHENTICATE_TIME_EPOCH_MILLIS = "last_password_entry_time_millis_epoch"; private static final String TABLE_AUTHTOKENS = "authtokens"; private static final String AUTHTOKENS_ID = "_id"; Loading Loading @@ -697,7 +699,8 @@ public class AccountManagerService long identityToken = clearCallingIdentity(); try { new Session(fromAccounts, response, account.type, false, false /* stripAuthTokenFromResult */) { false /* stripAuthTokenFromResult */, account.name, false /* authDetailsRequired */) { @Override protected String toDebugString(long now) { return super.toDebugString(now) + ", getAccountCredentialsForClone" Loading Loading @@ -725,12 +728,43 @@ public class AccountManagerService } } @Override public boolean accountAuthenticated(final Account account) { if (account == null) { throw new IllegalArgumentException("account is null"); } checkAuthenticateAccountsPermission(account); final UserAccounts accounts = getUserAccountsForCaller(); int userId = Binder.getCallingUserHandle().getIdentifier(); if (!canUserModifyAccounts(userId) || !canUserModifyAccountsForType(userId, account.type)) { return false; } synchronized (accounts.cacheLock) { final ContentValues values = new ContentValues(); values.put(ACCOUNTS_LAST_AUTHENTICATE_TIME_EPOCH_MILLIS, System.currentTimeMillis()); final SQLiteDatabase db = accounts.openHelper.getWritableDatabase(); int i = db.update( TABLE_ACCOUNTS, values, ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE + "=?", new String[] { account.name, account.type }); if (i > 0) { return true; } } return false; } private void completeCloningAccount(IAccountManagerResponse response, final Bundle accountCredentials, final Account account, final UserAccounts targetUser) { long id = clearCallingIdentity(); try { new Session(targetUser, response, account.type, false, false /* stripAuthTokenFromResult */) { false /* stripAuthTokenFromResult */, account.name, false /* authDetailsRequired */) { @Override protected String toDebugString(long now) { return super.toDebugString(now) + ", getAccountCredentialsForClone" Loading Loading @@ -795,6 +829,7 @@ public class AccountManagerService values.put(ACCOUNTS_NAME, account.name); values.put(ACCOUNTS_TYPE, account.type); values.put(ACCOUNTS_PASSWORD, password); values.put(ACCOUNTS_LAST_AUTHENTICATE_TIME_EPOCH_MILLIS, System.currentTimeMillis()); long accountId = db.insert(TABLE_ACCOUNTS, ACCOUNTS_NAME, values); if (accountId < 0) { Log.w(TAG, "insertAccountIntoDatabase: " + account Loading Loading @@ -885,7 +920,8 @@ public class AccountManagerService public TestFeaturesSession(UserAccounts accounts, IAccountManagerResponse response, Account account, String[] features) { super(accounts, response, account.type, false /* expectActivityLaunch */, true /* stripAuthTokenFromResult */); true /* stripAuthTokenFromResult */, account.name, false /* authDetailsRequired */); mFeatures = features; mAccount = account; } Loading Loading @@ -1184,7 +1220,8 @@ public class AccountManagerService public RemoveAccountSession(UserAccounts accounts, IAccountManagerResponse response, Account account, boolean expectActivityLaunch) { super(accounts, response, account.type, expectActivityLaunch, true /* stripAuthTokenFromResult */); true /* stripAuthTokenFromResult */, account.name, false /* authDetailsRequired */); mAccount = account; } Loading Loading @@ -1419,6 +1456,13 @@ public class AccountManagerService try { final ContentValues values = new ContentValues(); values.put(ACCOUNTS_PASSWORD, password); long time = 0; // Only set current time, if it is a valid password. For clear password case, it // should not be set. if (password != null) { time = System.currentTimeMillis(); } values.put(ACCOUNTS_LAST_AUTHENTICATE_TIME_EPOCH_MILLIS, time); final long accountId = getAccountIdLocked(db, account); if (accountId >= 0) { final String[] argsAccountId = {String.valueOf(accountId)}; Loading Loading @@ -1547,8 +1591,9 @@ public class AccountManagerService UserAccounts accounts = getUserAccounts(UserHandle.getUserId(callingUid)); long identityToken = clearCallingIdentity(); try { new Session(accounts, response, accountType, false, false /* stripAuthTokenFromResult */) { new Session(accounts, response, accountType, false /* expectActivityLaunch */, false /* stripAuthTokenFromResult */, null /* accountName */, false /* authDetailsRequired */) { @Override protected String toDebugString(long now) { return super.toDebugString(now) + ", getAuthTokenLabel" Loading Loading @@ -1648,7 +1693,8 @@ public class AccountManagerService } new Session(accounts, response, account.type, expectActivityLaunch, false /* stripAuthTokenFromResult */) { false /* stripAuthTokenFromResult */, account.name, false /* authDetailsRequired */) { @Override protected String toDebugString(long now) { if (loginOptions != null) loginOptions.keySet(); Loading Loading @@ -1842,7 +1888,8 @@ public class AccountManagerService long identityToken = clearCallingIdentity(); try { new Session(accounts, response, accountType, expectActivityLaunch, true /* stripAuthTokenFromResult */) { true /* stripAuthTokenFromResult */, null /* accountName */, false /* authDetailsRequired */) { @Override public void run() throws RemoteException { mAuthenticator.addAccount(this, mAccountType, authTokenType, requiredFeatures, Loading Loading @@ -1917,7 +1964,8 @@ public class AccountManagerService long identityToken = clearCallingIdentity(); try { new Session(accounts, response, accountType, expectActivityLaunch, true /* stripAuthTokenFromResult */) { true /* stripAuthTokenFromResult */, null /* accountName */, false /* authDetailsRequired */) { @Override public void run() throws RemoteException { mAuthenticator.addAccount(this, mAccountType, authTokenType, requiredFeatures, Loading Loading @@ -1973,7 +2021,8 @@ public class AccountManagerService long identityToken = clearCallingIdentity(); try { new Session(accounts, response, account.type, expectActivityLaunch, true /* stripAuthTokenFromResult */) { true /* stripAuthTokenFromResult */, account.name, true /* authDetailsRequired */) { @Override public void run() throws RemoteException { mAuthenticator.confirmCredentials(this, account, options); Loading Loading @@ -2009,7 +2058,8 @@ public class AccountManagerService long identityToken = clearCallingIdentity(); try { new Session(accounts, response, account.type, expectActivityLaunch, true /* stripAuthTokenFromResult */) { true /* stripAuthTokenFromResult */, account.name, false /* authDetailsRequired */) { @Override public void run() throws RemoteException { mAuthenticator.updateCredentials(this, account, authTokenType, loginOptions); Loading Loading @@ -2045,7 +2095,8 @@ public class AccountManagerService long identityToken = clearCallingIdentity(); try { new Session(accounts, response, accountType, expectActivityLaunch, true /* stripAuthTokenFromResult */) { true /* stripAuthTokenFromResult */, null /* accountName */, false /* authDetailsRequired */) { @Override public void run() throws RemoteException { mAuthenticator.editProperties(this, mAccountType); Loading @@ -2071,7 +2122,8 @@ public class AccountManagerService public GetAccountsByTypeAndFeatureSession(UserAccounts accounts, IAccountManagerResponse response, String type, String[] features, int callingUid) { super(accounts, response, type, false /* expectActivityLaunch */, true /* stripAuthTokenFromResult */); true /* stripAuthTokenFromResult */, null /* accountName */, false /* authDetailsRequired */); mCallingUid = callingUid; mFeatures = features; } Loading Loading @@ -2437,6 +2489,9 @@ public class AccountManagerService final String mAccountType; final boolean mExpectActivityLaunch; final long mCreationTime; final String mAccountName; // Indicates if we need to add auth details(like last credential time) final boolean mAuthDetailsRequired; public int mNumResults = 0; private int mNumRequestContinued = 0; Loading @@ -2448,7 +2503,8 @@ public class AccountManagerService protected final UserAccounts mAccounts; public Session(UserAccounts accounts, IAccountManagerResponse response, String accountType, boolean expectActivityLaunch, boolean stripAuthTokenFromResult) { boolean expectActivityLaunch, boolean stripAuthTokenFromResult, String accountName, boolean authDetailsRequired) { super(); //if (response == null) throw new IllegalArgumentException("response is null"); if (accountType == null) throw new IllegalArgumentException("accountType is null"); Loading @@ -2458,6 +2514,9 @@ public class AccountManagerService mAccountType = accountType; mExpectActivityLaunch = expectActivityLaunch; mCreationTime = SystemClock.elapsedRealtime(); mAccountName = accountName; mAuthDetailsRequired = authDetailsRequired; synchronized (mSessions) { mSessions.put(toString(), this); } Loading Loading @@ -2592,6 +2651,16 @@ public class AccountManagerService public void onResult(Bundle result) { mNumResults++; Intent intent = null; if (result != null && mAuthDetailsRequired) { long lastAuthenticatedTime = DatabaseUtils.longForQuery( mAccounts.openHelper.getReadableDatabase(), "select " + ACCOUNTS_LAST_AUTHENTICATE_TIME_EPOCH_MILLIS + " from " + TABLE_ACCOUNTS + " WHERE " + ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE + "=?", new String[]{mAccountName, mAccountType}); result.putLong(AccountManager.KEY_LAST_AUTHENTICATE_TIME_MILLIS_EPOCH, lastAuthenticatedTime); } if (result != null && (intent = result.getParcelable(AccountManager.KEY_INTENT)) != null) { /* Loading Loading @@ -2798,6 +2867,7 @@ public class AccountManagerService + ACCOUNTS_TYPE + " TEXT NOT NULL, " + ACCOUNTS_PASSWORD + " TEXT, " + ACCOUNTS_PREVIOUS_NAME + " TEXT, " + ACCOUNTS_LAST_AUTHENTICATE_TIME_EPOCH_MILLIS + " INTEGER DEFAULT 0, " + "UNIQUE(" + ACCOUNTS_NAME + "," + ACCOUNTS_TYPE + "))"); db.execSQL("CREATE TABLE " + TABLE_AUTHTOKENS + " ( " Loading Loading @@ -2833,6 +2903,11 @@ public class AccountManagerService + "UNIQUE(" + ACCOUNTS_NAME + "," + ACCOUNTS_TYPE + "))"); } private void addLastSuccessfullAuthenticatedTimeColumn(SQLiteDatabase db) { db.execSQL("ALTER TABLE " + TABLE_ACCOUNTS + " ADD COLUMN " + ACCOUNTS_LAST_AUTHENTICATE_TIME_EPOCH_MILLIS + " DEFAULT 0"); } private void addOldAccountNameColumn(SQLiteDatabase db) { db.execSQL("ALTER TABLE " + TABLE_ACCOUNTS + " ADD COLUMN " + ACCOUNTS_PREVIOUS_NAME); } Loading Loading @@ -2892,6 +2967,11 @@ public class AccountManagerService oldVersion++; } if (oldVersion == 6) { addLastSuccessfullAuthenticatedTimeColumn(db); oldVersion++; } if (oldVersion != newVersion) { Log.e(TAG, "failed to upgrade version " + oldVersion + " to version " + newVersion); } Loading