Fix a race condition in SyncManager.onAccountsUpdated()
Get the full list of accounts from AccountManagerService in one shot instead of getting them per user. Bug: 6263091 Change-Id: I488f24749a96281ef1e2a620820399c97f471024
This commit is contained in:
49
core/java/android/accounts/AccountAndUser.java
Normal file
49
core/java/android/accounts/AccountAndUser.java
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (C) 2012 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;
|
||||
|
||||
/**
|
||||
* Used to store the Account and the UserId this account is associated with.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public class AccountAndUser {
|
||||
public Account account;
|
||||
public int userId;
|
||||
|
||||
public AccountAndUser(Account account, int userId) {
|
||||
this.account = account;
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof AccountAndUser)) return false;
|
||||
final AccountAndUser other = (AccountAndUser) o;
|
||||
return this.account.equals(other.account)
|
||||
&& this.userId == other.userId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return account.hashCode() + userId;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return account.toString() + " u" + userId;
|
||||
}
|
||||
}
|
||||
@@ -1488,6 +1488,31 @@ public class AccountManagerService
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all the accounts qualified by user.
|
||||
* @hide
|
||||
*/
|
||||
public AccountAndUser[] getAllAccounts() {
|
||||
ArrayList<AccountAndUser> allAccounts = new ArrayList<AccountAndUser>();
|
||||
List<UserInfo> users = getAllUsers();
|
||||
if (users == null) return new AccountAndUser[0];
|
||||
|
||||
synchronized(mUsers) {
|
||||
for (UserInfo user : users) {
|
||||
UserAccounts userAccounts = getUserAccounts(user.id);
|
||||
if (userAccounts == null) continue;
|
||||
synchronized (userAccounts.cacheLock) {
|
||||
Account[] accounts = getAccountsFromCacheLocked(userAccounts, null);
|
||||
for (int a = 0; a < accounts.length; a++) {
|
||||
allAccounts.add(new AccountAndUser(accounts[a], user.id));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
AccountAndUser[] accountsArray = new AccountAndUser[allAccounts.size()];
|
||||
return allAccounts.toArray(accountsArray);
|
||||
}
|
||||
|
||||
public Account[] getAccounts(String type) {
|
||||
if (Log.isLoggable(TAG, Log.VERBOSE)) {
|
||||
Log.v(TAG, "getAccounts: accountType " + type
|
||||
|
||||
@@ -22,6 +22,7 @@ import com.google.android.collect.Lists;
|
||||
import com.google.android.collect.Maps;
|
||||
|
||||
import android.accounts.Account;
|
||||
import android.accounts.AccountAndUser;
|
||||
import android.accounts.AccountManager;
|
||||
import android.accounts.AccountManagerService;
|
||||
import android.accounts.OnAccountsUpdateListener;
|
||||
@@ -237,22 +238,14 @@ public class SyncManager implements OnAccountsUpdateListener {
|
||||
|
||||
int count = 0;
|
||||
|
||||
// For all known users on the system, get their accounts and add them to the list
|
||||
// Get accounts from AccountManager for all the users on the system
|
||||
// TODO: Limit this to active users, when such a concept exists.
|
||||
AccountAndUser[] allAccounts = AccountManagerService.getSingleton().getAllAccounts();
|
||||
for (UserInfo user : users) {
|
||||
accounts = AccountManagerService.getSingleton().getAccounts(user.id);
|
||||
count += accounts.length;
|
||||
}
|
||||
|
||||
AccountAndUser[] allAccounts = new AccountAndUser[count];
|
||||
int index = 0;
|
||||
for (UserInfo user : users) {
|
||||
accounts = AccountManagerService.getSingleton().getAccounts(user.id);
|
||||
for (Account account : accounts) {
|
||||
allAccounts[index++] = new AccountAndUser(account, user.id);
|
||||
}
|
||||
if (mBootCompleted) {
|
||||
mSyncStorageEngine.doDatabaseCleanup(accounts, user.id);
|
||||
Account[] accountsForUser =
|
||||
AccountManagerService.getSingleton().getAccounts(user.id);
|
||||
mSyncStorageEngine.doDatabaseCleanup(accountsForUser, user.id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -338,33 +331,6 @@ public class SyncManager implements OnAccountsUpdateListener {
|
||||
|
||||
private volatile boolean mBootCompleted = false;
|
||||
|
||||
static class AccountAndUser {
|
||||
Account account;
|
||||
int userId;
|
||||
|
||||
AccountAndUser(Account account, int userId) {
|
||||
this.account = account;
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof AccountAndUser)) return false;
|
||||
final AccountAndUser other = (AccountAndUser) o;
|
||||
return this.account.equals(other.account)
|
||||
&& this.userId == other.userId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return account.hashCode() + userId;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return account.toString() + " u" + userId;
|
||||
}
|
||||
}
|
||||
|
||||
private ConnectivityManager getConnectivityManager() {
|
||||
synchronized (this) {
|
||||
if (mConnManagerDoNotUseDirectly == null) {
|
||||
|
||||
@@ -25,7 +25,7 @@ import org.xmlpull.v1.XmlPullParserException;
|
||||
import org.xmlpull.v1.XmlSerializer;
|
||||
|
||||
import android.accounts.Account;
|
||||
import android.content.SyncManager.AccountAndUser;
|
||||
import android.accounts.AccountAndUser;
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.database.sqlite.SQLiteException;
|
||||
|
||||
Reference in New Issue
Block a user