AccountManagerService.java revision 26ff6626fc4ee0ae46f01ad309b366921da589fe
1603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana/* 2603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * Copyright (C) 2009 The Android Open Source Project 3603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * 4603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * Licensed under the Apache License, Version 2.0 (the "License"); 5603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * you may not use this file except in compliance with the License. 6603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * You may obtain a copy of the License at 7603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * 8603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * http://www.apache.org/licenses/LICENSE-2.0 9603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * 10603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * Unless required by applicable law or agreed to in writing, software 11603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * distributed under the License is distributed on an "AS IS" BASIS, 12603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * See the License for the specific language governing permissions and 14603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * limitations under the License. 15603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana */ 16603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 17603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintanapackage android.accounts; 18603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 19885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongkerimport android.Manifest; 203b4fcbc9f13bab6a2e9e5c37cc5e18fec7341c04Brett Chabotimport android.app.ActivityManager; 2104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasaniimport android.app.AppGlobals; 22885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongkerimport android.app.Notification; 23885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongkerimport android.app.NotificationManager; 24885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongkerimport android.app.PendingIntent; 25a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.content.BroadcastReceiver; 26885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongkerimport android.content.ComponentName; 27a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.content.ContentValues; 28a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.content.Context; 29a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.content.Intent; 30a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.content.IntentFilter; 31b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintanaimport android.content.ServiceConnection; 32885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongkerimport android.content.pm.ApplicationInfo; 33885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongkerimport android.content.pm.PackageInfo; 34d4a1d2e14297a3387fdb5761090961e714370492Fred Quintanaimport android.content.pm.PackageManager; 35d4a1d2e14297a3387fdb5761090961e714370492Fred Quintanaimport android.content.pm.RegisteredServicesCache; 363ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintanaimport android.content.pm.RegisteredServicesCacheListener; 3704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasaniimport android.content.pm.UserInfo; 3846703b099516c383a6882815bcf9cd4df0ec538dBrian Carlstromimport android.content.res.Resources; 39603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintanaimport android.database.Cursor; 40603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintanaimport android.database.DatabaseUtils; 41a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.database.sqlite.SQLiteDatabase; 42a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.database.sqlite.SQLiteOpenHelper; 43885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongkerimport android.os.Binder; 44a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.os.Bundle; 45a8529f68671a8a118751cb6ad577f44eaf076b96Oscar Montemayorimport android.os.Environment; 46a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.os.Handler; 47a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.os.HandlerThread; 48a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.os.IBinder; 49a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.os.Looper; 50a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.os.Message; 51a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.os.RemoteException; 52a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.os.SystemClock; 5304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasaniimport android.os.UserId; 54a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.text.TextUtils; 55a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.util.Log; 56d4a1d2e14297a3387fdb5761090961e714370492Fred Quintanaimport android.util.Pair; 5704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasaniimport android.util.SparseArray; 58603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 59b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolacheimport com.android.internal.R; 6004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasaniimport com.android.internal.util.IndentingPrintWriter; 61b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache 62a8529f68671a8a118751cb6ad577f44eaf076b96Oscar Montemayorimport java.io.File; 63a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport java.io.FileDescriptor; 64a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport java.io.PrintWriter; 65a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport java.util.ArrayList; 6656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintanaimport java.util.Arrays; 67a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport java.util.Collection; 68d4a1d2e14297a3387fdb5761090961e714370492Fred Quintanaimport java.util.HashMap; 6956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintanaimport java.util.LinkedHashMap; 7004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasaniimport java.util.List; 712f36229db823d152f3efd879e751e81a601a75b0Andy McFaddenimport java.util.Map; 72d4a1d2e14297a3387fdb5761090961e714370492Fred Quintanaimport java.util.concurrent.atomic.AtomicInteger; 73d4a1d2e14297a3387fdb5761090961e714370492Fred Quintanaimport java.util.concurrent.atomic.AtomicReference; 74603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 75603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana/** 76603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * A system service that provides account, password, and authtoken management for all 77603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * accounts on the device. Some of these calls are implemented with the help of the corresponding 78603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * {@link IAccountAuthenticator} services. This service is not accessed by users directly, 79603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * instead one uses an instance of {@link AccountManager}, which can be accessed as follows: 8046703b099516c383a6882815bcf9cd4df0ec538dBrian Carlstrom * AccountManager accountManager = AccountManager.get(context); 813326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana * @hide 82603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana */ 833ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintanapublic class AccountManagerService 843ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintana extends IAccountManager.Stub 855ebbb4a6b3e16f711735ae0615b9a9ea64faad38Fred Quintana implements RegisteredServicesCacheListener<AuthenticatorDescription> { 86603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String TAG = "AccountManagerService"; 87603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 88603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final int TIMEOUT_DELAY_MS = 1000 * 60; 89603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String DATABASE_NAME = "accounts.db"; 903348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache private static final int DATABASE_VERSION = 4; 91603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 92603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private final Context mContext; 93603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 9456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana private final PackageManager mPackageManager; 9556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 96603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private HandlerThread mMessageThread; 97603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private final MessageHandler mMessageHandler; 98603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 99603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana // Messages that can be sent on mHandler 100603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final int MESSAGE_TIMED_OUT = 3; 101603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 10256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana private final IAccountAuthenticatorCache mAuthenticatorCache; 103603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 104603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String TABLE_ACCOUNTS = "accounts"; 105603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String ACCOUNTS_ID = "_id"; 106603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String ACCOUNTS_NAME = "name"; 107603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String ACCOUNTS_TYPE = "type"; 1081cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks private static final String ACCOUNTS_TYPE_COUNT = "count(type)"; 109603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String ACCOUNTS_PASSWORD = "password"; 110603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 111603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String TABLE_AUTHTOKENS = "authtokens"; 112603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String AUTHTOKENS_ID = "_id"; 113603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String AUTHTOKENS_ACCOUNTS_ID = "accounts_id"; 114603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String AUTHTOKENS_TYPE = "type"; 115603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String AUTHTOKENS_AUTHTOKEN = "authtoken"; 116603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 117d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private static final String TABLE_GRANTS = "grants"; 118d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private static final String GRANTS_ACCOUNTS_ID = "accounts_id"; 119d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private static final String GRANTS_AUTH_TOKEN_TYPE = "auth_token_type"; 120d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private static final String GRANTS_GRANTEE_UID = "uid"; 121d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 122603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String TABLE_EXTRAS = "extras"; 123603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String EXTRAS_ID = "_id"; 124603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String EXTRAS_ACCOUNTS_ID = "accounts_id"; 125603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String EXTRAS_KEY = "key"; 126603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String EXTRAS_VALUE = "value"; 127603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 128603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String TABLE_META = "meta"; 129603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String META_KEY = "key"; 130603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String META_VALUE = "value"; 131603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1321cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks private static final String[] ACCOUNT_TYPE_COUNT_PROJECTION = 1331cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks new String[] { ACCOUNTS_TYPE, ACCOUNTS_TYPE_COUNT}; 1347be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana private static final Intent ACCOUNTS_CHANGED_INTENT; 135a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 136d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private static final String COUNT_OF_MATCHING_GRANTS = "" 137d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + "SELECT COUNT(*) FROM " + TABLE_GRANTS + ", " + TABLE_ACCOUNTS 138d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + " WHERE " + GRANTS_ACCOUNTS_ID + "=" + ACCOUNTS_ID 139d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + " AND " + GRANTS_GRANTEE_UID + "=?" 140d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + " AND " + GRANTS_AUTH_TOKEN_TYPE + "=?" 141d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + " AND " + ACCOUNTS_NAME + "=?" 142d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + " AND " + ACCOUNTS_TYPE + "=?"; 143d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 14456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana private static final String SELECTION_AUTHTOKENS_BY_ACCOUNT = 14556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana AUTHTOKENS_ACCOUNTS_ID + "=(select _id FROM accounts WHERE name=? AND type=?)"; 14656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana private static final String[] COLUMNS_AUTHTOKENS_TYPE_AND_AUTHTOKEN = {AUTHTOKENS_TYPE, 14756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana AUTHTOKENS_AUTHTOKEN}; 14856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 14956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana private static final String SELECTION_USERDATA_BY_ACCOUNT = 15056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana EXTRAS_ACCOUNTS_ID + "=(select _id FROM accounts WHERE name=? AND type=?)"; 15156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana private static final String[] COLUMNS_EXTRAS_KEY_AND_VALUE = {EXTRAS_KEY, EXTRAS_VALUE}; 15256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 153a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana private final LinkedHashMap<String, Session> mSessions = new LinkedHashMap<String, Session>(); 154d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private final AtomicInteger mNotificationIds = new AtomicInteger(1); 155d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 15604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani static class UserAccounts { 15704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private final int userId; 15804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private final DatabaseHelper openHelper; 15904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private final HashMap<Pair<Pair<Account, String>, Integer>, Integer> 16004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani credentialsPermissionNotificationIds = 16104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani new HashMap<Pair<Pair<Account, String>, Integer>, Integer>(); 16204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private final HashMap<Account, Integer> signinRequiredNotificationIds = 16304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani new HashMap<Account, Integer>(); 16404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private final Object cacheLock = new Object(); 16504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani /** protected by the {@link #cacheLock} */ 166b483a99c6bdfee72fbb8fbcf893e63ef3f54658bAmith Yamasani private final HashMap<String, Account[]> accountCache = 167b483a99c6bdfee72fbb8fbcf893e63ef3f54658bAmith Yamasani new LinkedHashMap<String, Account[]>(); 16804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani /** protected by the {@link #cacheLock} */ 16904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private HashMap<Account, HashMap<String, String>> userDataCache = 17004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani new HashMap<Account, HashMap<String, String>>(); 17104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani /** protected by the {@link #cacheLock} */ 17204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private HashMap<Account, HashMap<String, String>> authTokenCache = 17304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani new HashMap<Account, HashMap<String, String>>(); 17404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani 17504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts(Context context, int userId) { 17604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani this.userId = userId; 17704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (cacheLock) { 17804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani openHelper = new DatabaseHelper(context, userId); 17904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 18004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 18104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 18204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani 18304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private final SparseArray<UserAccounts> mUsers = new SparseArray<UserAccounts>(); 18404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani 185d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private static AtomicReference<AccountManagerService> sThis = 186d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana new AtomicReference<AccountManagerService>(); 18731957f1badbb900bbfe211317e1ea992d650a72dFred Quintana private static final Account[] EMPTY_ACCOUNT_ARRAY = new Account[]{}; 1887be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana 1897be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana static { 190f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana ACCOUNTS_CHANGED_INTENT = new Intent(AccountManager.LOGIN_ACCOUNTS_CHANGED_ACTION); 1917be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana ACCOUNTS_CHANGED_INTENT.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 1927be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana } 1937be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana 19456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 195d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana /** 196d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * This should only be called by system code. One should only call this after the service 197d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * has started. 198d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * @return a reference to the AccountManagerService instance 199d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * @hide 200d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana */ 201d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana public static AccountManagerService getSingleton() { 202d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana return sThis.get(); 203d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 204603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 20556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana public AccountManagerService(Context context) { 20656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana this(context, context.getPackageManager(), new AccountAuthenticatorCache(context)); 207603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 208603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 20956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana public AccountManagerService(Context context, PackageManager packageManager, 21056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana IAccountAuthenticatorCache authenticatorCache) { 211603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mContext = context; 21256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana mPackageManager = packageManager; 213603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 214603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mMessageThread = new HandlerThread("AccountManagerService"); 215603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mMessageThread.start(); 216603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mMessageHandler = new MessageHandler(mMessageThread.getLooper()); 217603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 21856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana mAuthenticatorCache = authenticatorCache; 2195ebbb4a6b3e16f711735ae0615b9a9ea64faad38Fred Quintana mAuthenticatorCache.setListener(this, null /* Handler */); 220603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 221d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana sThis.set(this); 222afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana 223c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana IntentFilter intentFilter = new IntentFilter(); 224c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED); 225c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana intentFilter.addDataScheme("package"); 226c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana mContext.registerReceiver(new BroadcastReceiver() { 227c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana @Override 228c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana public void onReceive(Context context1, Intent intent) { 22904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani purgeOldGrantsAll(); 230c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana } 231c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana }, intentFilter); 232c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana 233135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani IntentFilter userFilter = new IntentFilter(); 234135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani userFilter.addAction(Intent.ACTION_USER_REMOVED); 235135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani mContext.registerReceiver(new BroadcastReceiver() { 236135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani @Override 237135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani public void onReceive(Context context, Intent intent) { 238135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani onUserRemoved(intent); 239135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani } 240135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani }, userFilter); 241afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana } 242afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana 24326ff6626fc4ee0ae46f01ad309b366921da589feKenny Root public void systemReady() { 24426ff6626fc4ee0ae46f01ad309b366921da589feKenny Root mAuthenticatorCache.generateServicesMap(); 24526ff6626fc4ee0ae46f01ad309b366921da589feKenny Root initUser(0); 24626ff6626fc4ee0ae46f01ad309b366921da589feKenny Root } 24726ff6626fc4ee0ae46f01ad309b366921da589feKenny Root 24804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private UserAccounts initUser(int userId) { 24904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (mUsers) { 25004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = mUsers.get(userId); 25104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani if (accounts == null) { 25204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts = new UserAccounts(mContext, userId); 25304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani mUsers.append(userId, accounts); 25404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani purgeOldGrants(accounts); 25504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani validateAccountsAndPopulateCache(accounts); 25604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 25704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani return accounts; 25804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 25904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 26004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani 26104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private void purgeOldGrantsAll() { 26204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (mUsers) { 26304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani for (int i = 0; i < mUsers.size(); i++) { 26404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani purgeOldGrants(mUsers.valueAt(i)); 26504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 26604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 26704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 26804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani 26904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private void purgeOldGrants(UserAccounts accounts) { 27004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 27104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getWritableDatabase(); 272c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana final Cursor cursor = db.query(TABLE_GRANTS, 273c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana new String[]{GRANTS_GRANTEE_UID}, 274c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana null, null, GRANTS_GRANTEE_UID, null, null); 275c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana try { 276c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana while (cursor.moveToNext()) { 277c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana final int uid = cursor.getInt(0); 278c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana final boolean packageExists = mPackageManager.getPackagesForUid(uid) != null; 279c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana if (packageExists) { 280c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana continue; 281c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana } 282c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana Log.d(TAG, "deleting grants for UID " + uid 283c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana + " because its package is no longer installed"); 284c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana db.delete(TABLE_GRANTS, GRANTS_GRANTEE_UID + "=?", 285c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana new String[]{Integer.toString(uid)}); 286c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana } 287c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana } finally { 288c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana cursor.close(); 289c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana } 290c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana } 291c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana } 292c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana 29304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private void validateAccountsAndPopulateCache(UserAccounts accounts) { 29404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 29504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getWritableDatabase(); 296f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana boolean accountDeleted = false; 297f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana Cursor cursor = db.query(TABLE_ACCOUNTS, 298f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana new String[]{ACCOUNTS_ID, ACCOUNTS_TYPE, ACCOUNTS_NAME}, 299f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana null, null, null, null, null); 300f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana try { 30104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.accountCache.clear(); 30256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final HashMap<String, ArrayList<String>> accountNamesByType = 303b483a99c6bdfee72fbb8fbcf893e63ef3f54658bAmith Yamasani new LinkedHashMap<String, ArrayList<String>>(); 30456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana while (cursor.moveToNext()) { 30556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final long accountId = cursor.getLong(0); 30656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final String accountType = cursor.getString(1); 30756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final String accountName = cursor.getString(2); 30856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (mAuthenticatorCache.getServiceInfo( 30956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana AuthenticatorDescription.newKey(accountType)) == null) { 31056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.d(TAG, "deleting account " + accountName + " because type " 31156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + accountType + " no longer has a registered authenticator"); 31256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana db.delete(TABLE_ACCOUNTS, ACCOUNTS_ID + "=" + accountId, null); 31356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana accountDeleted = true; 31456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final Account account = new Account(accountName, accountType); 31504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.userDataCache.remove(account); 31604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.authTokenCache.remove(account); 31756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } else { 31856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana ArrayList<String> accountNames = accountNamesByType.get(accountType); 31956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (accountNames == null) { 32056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana accountNames = new ArrayList<String>(); 32156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana accountNamesByType.put(accountType, accountNames); 32256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 32356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana accountNames.add(accountName); 32456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 32556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 3262f36229db823d152f3efd879e751e81a601a75b0Andy McFadden for (Map.Entry<String, ArrayList<String>> cur 327f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana : accountNamesByType.entrySet()) { 32856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final String accountType = cur.getKey(); 32956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final ArrayList<String> accountNames = cur.getValue(); 33056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final Account[] accountsForType = new Account[accountNames.size()]; 33156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana int i = 0; 33256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana for (String accountName : accountNames) { 33356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana accountsForType[i] = new Account(accountName, accountType); 33456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana ++i; 33556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 33604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.accountCache.put(accountType, accountsForType); 337afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana } 338f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } finally { 339f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana cursor.close(); 340f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (accountDeleted) { 34104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani sendAccountsChangedBroadcast(accounts.userId); 342f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 343afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana } 344afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana } 3453ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintana } 3463ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintana 34704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private UserAccounts getUserAccountsForCaller() { 34804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani return getUserAccounts(UserId.getCallingUserId()); 34904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 35004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani 35104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani protected UserAccounts getUserAccounts(int userId) { 35204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (mUsers) { 35304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = mUsers.get(userId); 35404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani if (accounts == null) { 35504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts = initUser(userId); 35604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani mUsers.append(userId, accounts); 35704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 35804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani return accounts; 35904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 36004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 36104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani 362135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani private void onUserRemoved(Intent intent) { 363135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani int userId = intent.getIntExtra(Intent.EXTRA_USERID, -1); 364135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani if (userId < 1) return; 365135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani 366135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani UserAccounts accounts; 367135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani synchronized (mUsers) { 368135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani accounts = mUsers.get(userId); 369135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani mUsers.remove(userId); 370135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani } 371135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani if (accounts == null) { 372135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani File dbFile = new File(getDatabaseName(userId)); 373135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani dbFile.delete(); 374135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani return; 375135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani } 376135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani 377135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani synchronized (accounts.cacheLock) { 378135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani accounts.openHelper.close(); 379135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani File dbFile = new File(getDatabaseName(userId)); 380135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani dbFile.delete(); 381135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani } 382135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani } 383135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani 38404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private List<UserInfo> getAllUsers() { 38504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani try { 38604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani return AppGlobals.getPackageManager().getUsers(); 38704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } catch (RemoteException re) { 38804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani // Local to system process, shouldn't happen 38904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 39004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani return null; 39104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 39204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani 3935ebbb4a6b3e16f711735ae0615b9a9ea64faad38Fred Quintana public void onServiceChanged(AuthenticatorDescription desc, boolean removed) { 39404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani // Validate accounts for all users 39504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani List<UserInfo> users = getAllUsers(); 39604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani if (users == null) { 39704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani validateAccountsAndPopulateCache(getUserAccountsForCaller()); 39804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } else { 39904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani for (UserInfo user : users) { 40004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani validateAccountsAndPopulateCache(getUserAccounts(user.id)); 40104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 40204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 403603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 404603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 405a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public String getPassword(Account account) { 40656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 40756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "getPassword: " + account 40856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 40956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 41056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 411382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 412d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkAuthenticateAccountsPermission(account); 413d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 41404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 41526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 416603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana try { 41704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani return readPasswordInternal(accounts, account); 418603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } finally { 41926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 420603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 421603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 422603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 42304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private String readPasswordInternal(UserAccounts accounts, Account account) { 42431957f1badbb900bbfe211317e1ea992d650a72dFred Quintana if (account == null) { 42531957f1badbb900bbfe211317e1ea992d650a72dFred Quintana return null; 42631957f1badbb900bbfe211317e1ea992d650a72dFred Quintana } 42731957f1badbb900bbfe211317e1ea992d650a72dFred Quintana 42804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 42904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getReadableDatabase(); 430f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana Cursor cursor = db.query(TABLE_ACCOUNTS, new String[]{ACCOUNTS_PASSWORD}, 431f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?", 432f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana new String[]{account.name, account.type}, null, null, null); 433f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana try { 434f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (cursor.moveToNext()) { 435f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return cursor.getString(0); 436f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 437f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return null; 438f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } finally { 439f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana cursor.close(); 440ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 441ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 442ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 443ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 444a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public String getUserData(Account account, String key) { 44556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 44656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "getUserData: " + account 44756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", key " + key 44856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 44956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 45056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 451382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 452382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (key == null) throw new IllegalArgumentException("key is null"); 453d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkAuthenticateAccountsPermission(account); 45404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 45526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 456603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana try { 45704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani return readUserDataInternal(accounts, account, key); 458ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } finally { 459ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana restoreCallingIdentity(identityToken); 460ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 461ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 462ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 4639788976b1465ce982b5ae7c741345edd0ecd9322Fred Quintana public AuthenticatorDescription[] getAuthenticatorTypes() { 46456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 46556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "getAuthenticatorTypes: " 46656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + "caller's uid " + Binder.getCallingUid() 46756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 46856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 46926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 47026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 4719788976b1465ce982b5ae7c741345edd0ecd9322Fred Quintana Collection<AccountAuthenticatorCache.ServiceInfo<AuthenticatorDescription>> 4729788976b1465ce982b5ae7c741345edd0ecd9322Fred Quintana authenticatorCollection = mAuthenticatorCache.getAllServices(); 4739788976b1465ce982b5ae7c741345edd0ecd9322Fred Quintana AuthenticatorDescription[] types = 4749788976b1465ce982b5ae7c741345edd0ecd9322Fred Quintana new AuthenticatorDescription[authenticatorCollection.size()]; 47526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana int i = 0; 4769788976b1465ce982b5ae7c741345edd0ecd9322Fred Quintana for (AccountAuthenticatorCache.ServiceInfo<AuthenticatorDescription> authenticator 477718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana : authenticatorCollection) { 478718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana types[i] = authenticator.type; 47926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana i++; 48026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 48126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana return types; 48226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 48326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 484a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 485a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 486a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 487a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public boolean addAccount(Account account, String password, Bundle extras) { 48856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 48956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "addAccount: " + account 49056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 49156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 49256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 493382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 494d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkAuthenticateAccountsPermission(account); 495d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 49604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 497603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana // fails if the account already exists 49826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 499603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana try { 50004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani return addAccountInternal(accounts, account, password, extras); 501ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } finally { 502ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana restoreCallingIdentity(identityToken); 503ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 504ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 505ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 50604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private boolean addAccountInternal(UserAccounts accounts, Account account, String password, 50704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani Bundle extras) { 508743dfad2a51e016ddb741c104317637089187753Fred Quintana if (account == null) { 509743dfad2a51e016ddb741c104317637089187753Fred Quintana return false; 510743dfad2a51e016ddb741c104317637089187753Fred Quintana } 51104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 51204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getWritableDatabase(); 513f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.beginTransaction(); 514f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana try { 515f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana long numMatches = DatabaseUtils.longForQuery(db, 516f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana "select count(*) from " + TABLE_ACCOUNTS 517f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana + " WHERE " + ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?", 518f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana new String[]{account.name, account.type}); 519f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (numMatches > 0) { 520f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana Log.w(TAG, "insertAccountIntoDatabase: " + account 521f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana + ", skipping since the account already exists"); 522f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return false; 523f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 524f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana ContentValues values = new ContentValues(); 525f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana values.put(ACCOUNTS_NAME, account.name); 526f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana values.put(ACCOUNTS_TYPE, account.type); 527f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana values.put(ACCOUNTS_PASSWORD, password); 528f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana long accountId = db.insert(TABLE_ACCOUNTS, ACCOUNTS_NAME, values); 529f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (accountId < 0) { 530f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana Log.w(TAG, "insertAccountIntoDatabase: " + account 531f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana + ", skipping the DB insert failed"); 532f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return false; 533f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 534f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (extras != null) { 535f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana for (String key : extras.keySet()) { 536f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana final String value = extras.getString(key); 537f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (insertExtraLocked(db, accountId, key, value) < 0) { 538f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana Log.w(TAG, "insertAccountIntoDatabase: " + account 539f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana + ", skipping since insertExtra failed for key " + key); 540f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return false; 541f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 542603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 543603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 544f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.setTransactionSuccessful(); 54504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani insertAccountIntoCacheLocked(accounts, account); 546f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } finally { 547f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.endTransaction(); 548603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 54904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani sendAccountsChangedBroadcast(accounts.userId); 550f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return true; 551603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 552603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 553603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 554f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana private long insertExtraLocked(SQLiteDatabase db, long accountId, String key, String value) { 555603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana ContentValues values = new ContentValues(); 556603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana values.put(EXTRAS_KEY, key); 557603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana values.put(EXTRAS_ACCOUNTS_ID, accountId); 558603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana values.put(EXTRAS_VALUE, value); 559603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana return db.insert(TABLE_EXTRAS, EXTRAS_KEY, values); 560603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 561603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 5623084a6f80180506ce26fe4773d9a19f004b7f625Fred Quintana public void hasFeatures(IAccountManagerResponse response, 563bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana Account account, String[] features) { 56456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 56556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "hasFeatures: " + account 56656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", response " + response 56756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", features " + stringArrayToString(features) 56856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 56956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 57056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 571382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (response == null) throw new IllegalArgumentException("response is null"); 572382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 573382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (features == null) throw new IllegalArgumentException("features is null"); 574bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana checkReadAccountsPermission(); 57504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 576bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana long identityToken = clearCallingIdentity(); 577bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana try { 57804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani new TestFeaturesSession(accounts, response, account, features).bind(); 579bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } finally { 580bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana restoreCallingIdentity(identityToken); 581bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 582bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 583bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana 584bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana private class TestFeaturesSession extends Session { 585bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana private final String[] mFeatures; 586bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana private final Account mAccount; 587bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana 58804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani public TestFeaturesSession(UserAccounts accounts, IAccountManagerResponse response, 589bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana Account account, String[] features) { 59004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani super(accounts, response, account.type, false /* expectActivityLaunch */, 5918570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana true /* stripAuthTokenFromResult */); 592bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana mFeatures = features; 593bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana mAccount = account; 594bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 595bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana 596bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana public void run() throws RemoteException { 597bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana try { 598bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana mAuthenticator.hasFeatures(this, mAccount, mFeatures); 599bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } catch (RemoteException e) { 600bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana onError(AccountManager.ERROR_CODE_REMOTE_EXCEPTION, "remote exception"); 601bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 602bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 603bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana 604bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana public void onResult(Bundle result) { 605bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana IAccountManagerResponse response = getResponseAndClose(); 606bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana if (response != null) { 607bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana try { 608bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana if (result == null) { 609166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana response.onError(AccountManager.ERROR_CODE_INVALID_RESPONSE, "null bundle"); 610bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana return; 611bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 61256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 61356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, getClass().getSimpleName() + " calling onResult() on response " 61456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + response); 61556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 616bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana final Bundle newResult = new Bundle(); 617bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana newResult.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, 618bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT, false)); 619bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana response.onResult(newResult); 620bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } catch (RemoteException e) { 621bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana // if the caller is dead then there is no one to care about remote exceptions 622bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 623bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana Log.v(TAG, "failure while notifying response", e); 624bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 625bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 626bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 627bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 628bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana 629bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana protected String toDebugString(long now) { 6303084a6f80180506ce26fe4773d9a19f004b7f625Fred Quintana return super.toDebugString(now) + ", hasFeatures" 631bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana + ", " + mAccount 632bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana + ", " + (mFeatures != null ? TextUtils.join(",", mFeatures) : null); 633bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 634bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 635307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana 636ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana public void removeAccount(IAccountManagerResponse response, Account account) { 63756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 63856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "removeAccount: " + account 63956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", response " + response 64056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 64156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 64256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 643382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (response == null) throw new IllegalArgumentException("response is null"); 644382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 645d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkManageAccountsPermission(); 64604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 64726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 648ec0c4f4183630a64c2b2cc8f961dc7e11cc628caCostin Manolache 64904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani cancelNotification(getSigninRequiredNotificationId(accounts, account)); 65004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized(accounts.credentialsPermissionNotificationIds) { 651ec0c4f4183630a64c2b2cc8f961dc7e11cc628caCostin Manolache for (Pair<Pair<Account, String>, Integer> pair: 65204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.credentialsPermissionNotificationIds.keySet()) { 653ec0c4f4183630a64c2b2cc8f961dc7e11cc628caCostin Manolache if (account.equals(pair.first.first)) { 65404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani int id = accounts.credentialsPermissionNotificationIds.get(pair); 655ec0c4f4183630a64c2b2cc8f961dc7e11cc628caCostin Manolache cancelNotification(id); 656ec0c4f4183630a64c2b2cc8f961dc7e11cc628caCostin Manolache } 657ec0c4f4183630a64c2b2cc8f961dc7e11cc628caCostin Manolache } 658ec0c4f4183630a64c2b2cc8f961dc7e11cc628caCostin Manolache } 659ec0c4f4183630a64c2b2cc8f961dc7e11cc628caCostin Manolache 66026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 66104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani new RemoveAccountSession(accounts, response, account).bind(); 66226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 66326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 664a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 665603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 666603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 667ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana private class RemoveAccountSession extends Session { 668ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana final Account mAccount; 66904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani public RemoveAccountSession(UserAccounts accounts, IAccountManagerResponse response, 67004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani Account account) { 67104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani super(accounts, response, account.type, false /* expectActivityLaunch */, 6728570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana true /* stripAuthTokenFromResult */); 673ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana mAccount = account; 674ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 675ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 676ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana protected String toDebugString(long now) { 677ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana return super.toDebugString(now) + ", removeAccount" 678ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana + ", account " + mAccount; 679ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 680ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 681ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana public void run() throws RemoteException { 682ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana mAuthenticator.getAccountRemovalAllowed(this, mAccount); 683ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 684ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 685ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana public void onResult(Bundle result) { 686f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana if (result != null && result.containsKey(AccountManager.KEY_BOOLEAN_RESULT) 687f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana && !result.containsKey(AccountManager.KEY_INTENT)) { 688f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana final boolean removalAllowed = result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT); 689ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana if (removalAllowed) { 69004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani removeAccountInternal(mAccounts, mAccount); 691ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 692ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana IAccountManagerResponse response = getResponseAndClose(); 693ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana if (response != null) { 69456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 69556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, getClass().getSimpleName() + " calling onResult() on response " 69656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + response); 69756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 698ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana Bundle result2 = new Bundle(); 699f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana result2.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, removalAllowed); 700ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana try { 701ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana response.onResult(result2); 702ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } catch (RemoteException e) { 703ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana // ignore 704ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 705ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 706ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 707ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana super.onResult(result); 708ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 709ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 710ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 71104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani /* For testing */ 712f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana protected void removeAccountInternal(Account account) { 71304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani removeAccountInternal(getUserAccountsForCaller(), account); 71404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 71504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani 71604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private void removeAccountInternal(UserAccounts accounts, Account account) { 71704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 71804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getWritableDatabase(); 719f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.delete(TABLE_ACCOUNTS, ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?", 720f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana new String[]{account.name, account.type}); 72104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani removeAccountFromCacheLocked(accounts, account); 72204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani sendAccountsChangedBroadcast(accounts.userId); 723f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 724ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 725ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 726a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void invalidateAuthToken(String accountType, String authToken) { 72756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 72856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "invalidateAuthToken: accountType " + accountType 72956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 73056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 73156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 732382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (accountType == null) throw new IllegalArgumentException("accountType is null"); 733382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (authToken == null) throw new IllegalArgumentException("authToken is null"); 734b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana checkManageAccountsOrUseCredentialsPermissions(); 73504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 73626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 737603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana try { 73804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 73904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getWritableDatabase(); 740f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.beginTransaction(); 741f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana try { 74204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani invalidateAuthTokenLocked(accounts, db, accountType, authToken); 743f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.setTransactionSuccessful(); 744f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } finally { 745f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.endTransaction(); 746f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 74726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 748603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } finally { 74926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 750603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 751603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 752603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 75304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private void invalidateAuthTokenLocked(UserAccounts accounts, SQLiteDatabase db, 75404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani String accountType, String authToken) { 755ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana if (authToken == null || accountType == null) { 756ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana return; 757ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 7583326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana Cursor cursor = db.rawQuery( 7593326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana "SELECT " + TABLE_AUTHTOKENS + "." + AUTHTOKENS_ID 7603326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + ", " + TABLE_ACCOUNTS + "." + ACCOUNTS_NAME 7613326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + ", " + TABLE_AUTHTOKENS + "." + AUTHTOKENS_TYPE 7623326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + " FROM " + TABLE_ACCOUNTS 7633326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + " JOIN " + TABLE_AUTHTOKENS 7643326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + " ON " + TABLE_ACCOUNTS + "." + ACCOUNTS_ID 7653326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + " = " + AUTHTOKENS_ACCOUNTS_ID 7663326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + " WHERE " + AUTHTOKENS_AUTHTOKEN + " = ? AND " 7673326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + TABLE_ACCOUNTS + "." + ACCOUNTS_TYPE + " = ?", 7683326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana new String[]{authToken, accountType}); 7693326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana try { 7703326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana while (cursor.moveToNext()) { 7713326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana long authTokenId = cursor.getLong(0); 7723326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana String accountName = cursor.getString(1); 7733326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana String authTokenType = cursor.getString(2); 7743326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana db.delete(TABLE_AUTHTOKENS, AUTHTOKENS_ID + "=" + authTokenId, null); 77504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani writeAuthTokenIntoCacheLocked(accounts, db, new Account(accountName, accountType), 776f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana authTokenType, null); 777603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 7783326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } finally { 7793326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana cursor.close(); 780603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 781603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 782603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 78304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private boolean saveAuthTokenToDatabase(UserAccounts accounts, Account account, String type, 78404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani String authToken) { 78531957f1badbb900bbfe211317e1ea992d650a72dFred Quintana if (account == null || type == null) { 78631957f1badbb900bbfe211317e1ea992d650a72dFred Quintana return false; 78731957f1badbb900bbfe211317e1ea992d650a72dFred Quintana } 78804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani cancelNotification(getSigninRequiredNotificationId(accounts, account)); 78904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 79004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getWritableDatabase(); 791f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.beginTransaction(); 792f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana try { 793f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana long accountId = getAccountIdLocked(db, account); 794f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (accountId < 0) { 795f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return false; 796f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 797f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.delete(TABLE_AUTHTOKENS, 798f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana AUTHTOKENS_ACCOUNTS_ID + "=" + accountId + " AND " + AUTHTOKENS_TYPE + "=?", 799f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana new String[]{type}); 800f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana ContentValues values = new ContentValues(); 801f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana values.put(AUTHTOKENS_ACCOUNTS_ID, accountId); 802f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana values.put(AUTHTOKENS_TYPE, type); 803f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana values.put(AUTHTOKENS_AUTHTOKEN, authToken); 804f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (db.insert(TABLE_AUTHTOKENS, AUTHTOKENS_AUTHTOKEN, values) >= 0) { 805f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.setTransactionSuccessful(); 80604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani writeAuthTokenIntoCacheLocked(accounts, db, account, type, authToken); 807f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return true; 808f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 8093326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana return false; 810f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } finally { 811f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.endTransaction(); 8123326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 813603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 814603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 815603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 816a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public String peekAuthToken(Account account, String authTokenType) { 81756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 81856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "peekAuthToken: " + account 81956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", authTokenType " + authTokenType 82056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 82156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 82256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 823382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 824382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null"); 825d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkAuthenticateAccountsPermission(account); 82604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 82726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 82826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 82904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani return readAuthTokenInternal(accounts, account, authTokenType); 83026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 83126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 832603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 833603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 834603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 835a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void setAuthToken(Account account, String authTokenType, String authToken) { 83656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 83756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "setAuthToken: " + account 83856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", authTokenType " + authTokenType 83956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 84056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 84156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 842382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 843382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null"); 844d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkAuthenticateAccountsPermission(account); 84504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 84626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 84726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 84804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani saveAuthTokenToDatabase(accounts, account, authTokenType, authToken); 84926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 85026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 85126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 852603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 853603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 854a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void setPassword(Account account, String password) { 85556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 85656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "setAuthToken: " + account 85756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 85856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 85956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 860382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 861d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkAuthenticateAccountsPermission(account); 86204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 86326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 86426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 86504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani setPasswordInternal(accounts, account, password); 86626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 86726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 86826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 869603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 870603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 87104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private void setPasswordInternal(UserAccounts accounts, Account account, String password) { 87231957f1badbb900bbfe211317e1ea992d650a72dFred Quintana if (account == null) { 87331957f1badbb900bbfe211317e1ea992d650a72dFred Quintana return; 87431957f1badbb900bbfe211317e1ea992d650a72dFred Quintana } 87504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 87604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getWritableDatabase(); 877f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.beginTransaction(); 878f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana try { 879f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana final ContentValues values = new ContentValues(); 880f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana values.put(ACCOUNTS_PASSWORD, password); 881f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana final long accountId = getAccountIdLocked(db, account); 882f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (accountId >= 0) { 883f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana final String[] argsAccountId = {String.valueOf(accountId)}; 884f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.update(TABLE_ACCOUNTS, values, ACCOUNTS_ID + "=?", argsAccountId); 885f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.delete(TABLE_AUTHTOKENS, AUTHTOKENS_ACCOUNTS_ID + "=?", argsAccountId); 88604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.authTokenCache.remove(account); 887f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.setTransactionSuccessful(); 888f5ffe89e736caee1419f0acb469565d5100b8fb8Costin Manolache } 889f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } finally { 890f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.endTransaction(); 891d4a9d6c42bb412e27a8383aaacd051419d98a662Fred Quintana } 89204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani sendAccountsChangedBroadcast(accounts.userId); 893d4a9d6c42bb412e27a8383aaacd051419d98a662Fred Quintana } 8943ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintana } 8953ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintana 89604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private void sendAccountsChangedBroadcast(int userId) { 89756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.i(TAG, "the accounts changed, sending broadcast of " 89856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ACCOUNTS_CHANGED_INTENT.getAction()); 89904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani mContext.sendBroadcast(ACCOUNTS_CHANGED_INTENT, userId); 9003326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 9013326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 902a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void clearPassword(Account account) { 90356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 90456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "clearPassword: " + account 90556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 90656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 90756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 908382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 909d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkManageAccountsPermission(); 91004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 91126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 91226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 91304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani setPasswordInternal(accounts, account, null); 91426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 91526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 91626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 917603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 918603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 919a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void setUserData(Account account, String key, String value) { 92056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 92156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "setUserData: " + account 92256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", key " + key 92356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 92456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 92556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 926382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (key == null) throw new IllegalArgumentException("key is null"); 927382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 928d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkAuthenticateAccountsPermission(account); 92904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 93026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 931603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana try { 93204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani setUserdataInternal(accounts, account, key, value); 933ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } finally { 934ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana restoreCallingIdentity(identityToken); 935ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 936ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 937ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 93804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private void setUserdataInternal(UserAccounts accounts, Account account, String key, 93904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani String value) { 94031957f1badbb900bbfe211317e1ea992d650a72dFred Quintana if (account == null || key == null) { 94131957f1badbb900bbfe211317e1ea992d650a72dFred Quintana return; 94231957f1badbb900bbfe211317e1ea992d650a72dFred Quintana } 94304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 94404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getWritableDatabase(); 945f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.beginTransaction(); 946f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana try { 947f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana long accountId = getAccountIdLocked(db, account); 948f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (accountId < 0) { 949ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana return; 95026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 951f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana long extrasId = getExtrasIdLocked(db, accountId, key); 952f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (extrasId < 0 ) { 953f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana extrasId = insertExtraLocked(db, accountId, key, value); 954f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (extrasId < 0) { 955f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return; 956f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 957f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } else { 958f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana ContentValues values = new ContentValues(); 959f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana values.put(EXTRAS_VALUE, value); 960f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (1 != db.update(TABLE_EXTRAS, values, EXTRAS_ID + "=" + extrasId, null)) { 961f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return; 962f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 963ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 964f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 96504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani writeUserDataIntoCacheLocked(accounts, db, account, key, value); 966f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.setTransactionSuccessful(); 967f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } finally { 968f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.endTransaction(); 969603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 970603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 971603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 972603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 973d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private void onResult(IAccountManagerResponse response, Bundle result) { 97456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (result == null) { 97556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.e(TAG, "the result is unexpectedly null", new Exception()); 97656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 97756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 97856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, getClass().getSimpleName() + " calling onResult() on response " 97956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + response); 98056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 981d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana try { 982d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana response.onResult(result); 983d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } catch (RemoteException e) { 984d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana // if the caller is dead then there is no one to care about remote 985d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana // exceptions 986d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 987d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Log.v(TAG, "failure while notifying response", e); 988d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 989d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 990d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 991d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 992d9640ec712806508877868d08aafaa2d715ff441Fred Quintana public void getAuthTokenLabel(IAccountManagerResponse response, final String accountType, 993d9640ec712806508877868d08aafaa2d715ff441Fred Quintana final String authTokenType) 994d9640ec712806508877868d08aafaa2d715ff441Fred Quintana throws RemoteException { 995d9640ec712806508877868d08aafaa2d715ff441Fred Quintana if (accountType == null) throw new IllegalArgumentException("accountType is null"); 9965f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null"); 9975f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache 998d9640ec712806508877868d08aafaa2d715ff441Fred Quintana final int callingUid = getCallingUid(); 999d9640ec712806508877868d08aafaa2d715ff441Fred Quintana clearCallingIdentity(); 1000d9640ec712806508877868d08aafaa2d715ff441Fred Quintana if (callingUid != android.os.Process.SYSTEM_UID) { 1001d9640ec712806508877868d08aafaa2d715ff441Fred Quintana throw new SecurityException("can only call from system"); 1002d9640ec712806508877868d08aafaa2d715ff441Fred Quintana } 1003d9640ec712806508877868d08aafaa2d715ff441Fred Quintana UserAccounts accounts = getUserAccounts(UserId.getUserId(callingUid)); 10045f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache long identityToken = clearCallingIdentity(); 10055f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache try { 1006d9640ec712806508877868d08aafaa2d715ff441Fred Quintana new Session(accounts, response, accountType, false, 10075f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache false /* stripAuthTokenFromResult */) { 10085f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache protected String toDebugString(long now) { 10095f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache return super.toDebugString(now) + ", getAuthTokenLabel" 1010d9640ec712806508877868d08aafaa2d715ff441Fred Quintana + ", " + accountType 10115f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache + ", authTokenType " + authTokenType; 10125f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache } 10135f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache 10145f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache public void run() throws RemoteException { 10155f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache mAuthenticator.getAuthTokenLabel(this, authTokenType); 10165f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache } 10175f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache 10185f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache public void onResult(Bundle result) { 10195f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache if (result != null) { 10205f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache String label = result.getString(AccountManager.KEY_AUTH_TOKEN_LABEL); 10215f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache Bundle bundle = new Bundle(); 10225f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache bundle.putString(AccountManager.KEY_AUTH_TOKEN_LABEL, label); 10235f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache super.onResult(bundle); 10245f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache return; 10255f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache } else { 10265f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache super.onResult(result); 10275f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache } 10285f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache } 10295f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache }.bind(); 10305f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache } finally { 10315f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache restoreCallingIdentity(identityToken); 10325f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache } 10335f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache } 10345f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache 1035a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void getAuthToken(IAccountManagerResponse response, final Account account, 1036a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana final String authTokenType, final boolean notifyOnAuthFailure, 1037c6684f9e9790e92960504e9b32f20f27003d9f37Costin Manolache final boolean expectActivityLaunch, Bundle loginOptionsIn) { 103856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 103956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "getAuthToken: " + account 104056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", response " + response 104156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", authTokenType " + authTokenType 104256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", notifyOnAuthFailure " + notifyOnAuthFailure 104356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", expectActivityLaunch " + expectActivityLaunch 104456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 104556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 104656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 1047382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (response == null) throw new IllegalArgumentException("response is null"); 1048382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 1049382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null"); 1050d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkBinderPermission(Manifest.permission.USE_CREDENTIALS); 105104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 1052a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache AccountAuthenticatorCache.ServiceInfo<AuthenticatorDescription> authenticatorInfo = 1053a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache mAuthenticatorCache.getServiceInfo( 1054a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache AuthenticatorDescription.newKey(account.type)); 1055a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache final boolean customTokens = 1056a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache authenticatorInfo != null && authenticatorInfo.type.customTokens; 1057a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache 1058a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache // skip the check if customTokens 1059b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache final int callerUid = Binder.getCallingUid(); 1060a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache final boolean permissionGranted = customTokens || 1061a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache permissionIsGranted(account, authTokenType, callerUid); 1062a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache 1063c6684f9e9790e92960504e9b32f20f27003d9f37Costin Manolache final Bundle loginOptions = (loginOptionsIn == null) ? new Bundle() : 1064c6684f9e9790e92960504e9b32f20f27003d9f37Costin Manolache loginOptionsIn; 1065b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache // let authenticator know the identity of the caller 1066b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache loginOptions.putInt(AccountManager.KEY_CALLER_UID, callerUid); 1067b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache loginOptions.putInt(AccountManager.KEY_CALLER_PID, Binder.getCallingPid()); 1068b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache if (notifyOnAuthFailure) { 1069b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache loginOptions.putBoolean(AccountManager.KEY_NOTIFY_ON_FAILURE, true); 1070a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache } 1071b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache 107226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 107326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 1074d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana // if the caller has permission, do the peek. otherwise go the more expensive 1075d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana // route of starting a Session 1076a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache if (!customTokens && permissionGranted) { 107704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani String authToken = readAuthTokenInternal(accounts, account, authTokenType); 1078d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (authToken != null) { 107926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana Bundle result = new Bundle(); 1080f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana result.putString(AccountManager.KEY_AUTHTOKEN, authToken); 1081f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name); 1082f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana result.putString(AccountManager.KEY_ACCOUNT_TYPE, account.type); 1083d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana onResult(response, result); 1084d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana return; 1085a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1086a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1087603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 108804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani new Session(accounts, response, account.type, expectActivityLaunch, 10898570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana false /* stripAuthTokenFromResult */) { 109026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana protected String toDebugString(long now) { 109126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana if (loginOptions != null) loginOptions.keySet(); 109226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana return super.toDebugString(now) + ", getAuthToken" 109326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana + ", " + account 109426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana + ", authTokenType " + authTokenType 109526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana + ", loginOptions " + loginOptions 109626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana + ", notifyOnAuthFailure " + notifyOnAuthFailure; 109726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1098a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 109926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana public void run() throws RemoteException { 1100d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana // If the caller doesn't have permission then create and return the 1101d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana // "grant permission" intent instead of the "getAuthToken" intent. 1102d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (!permissionGranted) { 1103d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana mAuthenticator.getAuthTokenLabel(this, authTokenType); 1104d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } else { 1105d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana mAuthenticator.getAuthToken(this, account, authTokenType, loginOptions); 1106d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 110726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1108a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 110926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana public void onResult(Bundle result) { 111026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana if (result != null) { 1111f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana if (result.containsKey(AccountManager.KEY_AUTH_TOKEN_LABEL)) { 1112d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Intent intent = newGrantCredentialsPermissionIntent(account, callerUid, 1113d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana new AccountAuthenticatorResponse(this), 1114d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana authTokenType, 1115f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana result.getString(AccountManager.KEY_AUTH_TOKEN_LABEL)); 1116d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Bundle bundle = new Bundle(); 1117f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana bundle.putParcelable(AccountManager.KEY_INTENT, intent); 1118d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana onResult(bundle); 1119d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana return; 1120d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1121f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana String authToken = result.getString(AccountManager.KEY_AUTHTOKEN); 112226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana if (authToken != null) { 1123f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana String name = result.getString(AccountManager.KEY_ACCOUNT_NAME); 1124f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana String type = result.getString(AccountManager.KEY_ACCOUNT_TYPE); 112526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana if (TextUtils.isEmpty(type) || TextUtils.isEmpty(name)) { 1126f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana onError(AccountManager.ERROR_CODE_INVALID_RESPONSE, 112726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana "the type and name should not be empty"); 112826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana return; 112926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1130a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache if (!customTokens) { 113104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani saveAuthTokenToDatabase(mAccounts, new Account(name, type), 1132a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache authTokenType, authToken); 1133a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache } 1134a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1135603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1136f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana Intent intent = result.getParcelable(AccountManager.KEY_INTENT); 1137d606045070dcf6a011e49a7711d2f17d8f2de8c1Costin Manolache if (intent != null && notifyOnAuthFailure && !customTokens) { 113804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani doNotification(mAccounts, 1139f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana account, result.getString(AccountManager.KEY_AUTH_FAILED_MESSAGE), 114026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana intent); 114126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1142a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 114326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana super.onResult(result); 1144a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 114526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana }.bind(); 114626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 114726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 114826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1149603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1150603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1151d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private void createNoCredentialsPermissionNotification(Account account, Intent intent) { 1152d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana int uid = intent.getIntExtra( 1153d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana GrantCredentialsPermissionActivity.EXTRAS_REQUESTING_UID, -1); 1154d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana String authTokenType = intent.getStringExtra( 1155d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana GrantCredentialsPermissionActivity.EXTRAS_AUTH_TOKEN_TYPE); 1156d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana String authTokenLabel = intent.getStringExtra( 1157d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana GrantCredentialsPermissionActivity.EXTRAS_AUTH_TOKEN_LABEL); 1158d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 1159d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Notification n = new Notification(android.R.drawable.stat_sys_warning, null, 1160d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 0 /* when */); 1161ee452ee5359cdfa3c3fbf6783722d3aaa2ec5ca6Eric Fischer final String titleAndSubtitle = 1162ee452ee5359cdfa3c3fbf6783722d3aaa2ec5ca6Eric Fischer mContext.getString(R.string.permission_request_notification_with_subtitle, 1163ee452ee5359cdfa3c3fbf6783722d3aaa2ec5ca6Eric Fischer account.name); 1164ee452ee5359cdfa3c3fbf6783722d3aaa2ec5ca6Eric Fischer final int index = titleAndSubtitle.indexOf('\n'); 116585e7279d9cc1ee8e4dd1f993a9e61a9eb547ecbcCostin Manolache String title = titleAndSubtitle; 116685e7279d9cc1ee8e4dd1f993a9e61a9eb547ecbcCostin Manolache String subtitle = ""; 116785e7279d9cc1ee8e4dd1f993a9e61a9eb547ecbcCostin Manolache if (index > 0) { 116885e7279d9cc1ee8e4dd1f993a9e61a9eb547ecbcCostin Manolache title = titleAndSubtitle.substring(0, index); 116985e7279d9cc1ee8e4dd1f993a9e61a9eb547ecbcCostin Manolache subtitle = titleAndSubtitle.substring(index + 1); 117085e7279d9cc1ee8e4dd1f993a9e61a9eb547ecbcCostin Manolache } 1171d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana n.setLatestEventInfo(mContext, 1172ee452ee5359cdfa3c3fbf6783722d3aaa2ec5ca6Eric Fischer title, subtitle, 1173d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana PendingIntent.getActivity(mContext, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT)); 117456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana installNotification(getCredentialPermissionNotificationId(account, authTokenType, uid), n); 1175d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1176d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 11775f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache String getAccountLabel(String accountType) { 1178d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana RegisteredServicesCache.ServiceInfo<AuthenticatorDescription> serviceInfo = 11795f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache mAuthenticatorCache.getServiceInfo( 11805f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache AuthenticatorDescription.newKey(accountType)); 1181d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (serviceInfo == null) { 11825f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache throw new IllegalArgumentException("unknown account type: " + accountType); 1183d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1184d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 1185d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana final Context authContext; 1186d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana try { 1187d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana authContext = mContext.createPackageContext( 11885f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache serviceInfo.type.packageName, 0); 1189d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } catch (PackageManager.NameNotFoundException e) { 11905f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache throw new IllegalArgumentException("unknown account type: " + accountType); 1191d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 119246703b099516c383a6882815bcf9cd4df0ec538dBrian Carlstrom try { 119346703b099516c383a6882815bcf9cd4df0ec538dBrian Carlstrom return authContext.getString(serviceInfo.type.labelId); 119446703b099516c383a6882815bcf9cd4df0ec538dBrian Carlstrom } catch (Resources.NotFoundException e) { 119546703b099516c383a6882815bcf9cd4df0ec538dBrian Carlstrom throw new IllegalArgumentException("unknown account type: " + accountType); 119646703b099516c383a6882815bcf9cd4df0ec538dBrian Carlstrom } 11975f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache } 11985f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache 11995f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache private Intent newGrantCredentialsPermissionIntent(Account account, int uid, 12005f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache AccountAuthenticatorResponse response, String authTokenType, String authTokenLabel) { 1201d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 1202d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Intent intent = new Intent(mContext, GrantCredentialsPermissionActivity.class); 120346703b099516c383a6882815bcf9cd4df0ec538dBrian Carlstrom // See FLAG_ACTIVITY_NEW_TASK docs for limitations and benefits of the flag. 12049ec17366c17efd14c643ee88fa1132ab05197349Costin Manolache // Since it was set in Eclair+ we can't change it without breaking apps using 12059ec17366c17efd14c643ee88fa1132ab05197349Costin Manolache // the intent from a non-Activity context. 12069ec17366c17efd14c643ee88fa1132ab05197349Costin Manolache intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 1207d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana intent.addCategory( 1208d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana String.valueOf(getCredentialPermissionNotificationId(account, authTokenType, uid))); 12095f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache 1210d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana intent.putExtra(GrantCredentialsPermissionActivity.EXTRAS_ACCOUNT, account); 1211d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana intent.putExtra(GrantCredentialsPermissionActivity.EXTRAS_AUTH_TOKEN_TYPE, authTokenType); 1212d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana intent.putExtra(GrantCredentialsPermissionActivity.EXTRAS_RESPONSE, response); 1213d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana intent.putExtra(GrantCredentialsPermissionActivity.EXTRAS_REQUESTING_UID, uid); 12145f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache 1215d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana return intent; 1216d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1217d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 1218d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private Integer getCredentialPermissionNotificationId(Account account, String authTokenType, 1219d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana int uid) { 1220d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Integer id; 122104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccounts(UserId.getUserId(uid)); 122204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.credentialsPermissionNotificationIds) { 1223d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana final Pair<Pair<Account, String>, Integer> key = 1224d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana new Pair<Pair<Account, String>, Integer>( 1225d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana new Pair<Account, String>(account, authTokenType), uid); 122604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani id = accounts.credentialsPermissionNotificationIds.get(key); 1227d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (id == null) { 1228d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana id = mNotificationIds.incrementAndGet(); 122904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.credentialsPermissionNotificationIds.put(key, id); 1230d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1231d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1232d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana return id; 1233d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1234d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 123504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private Integer getSigninRequiredNotificationId(UserAccounts accounts, Account account) { 1236d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Integer id; 123704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.signinRequiredNotificationIds) { 123804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani id = accounts.signinRequiredNotificationIds.get(account); 1239d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (id == null) { 1240d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana id = mNotificationIds.incrementAndGet(); 124104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.signinRequiredNotificationIds.put(account, id); 1242d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1243d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1244d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana return id; 1245d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1246d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 12473326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana public void addAcount(final IAccountManagerResponse response, final String accountType, 12483326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana final String authTokenType, final String[] requiredFeatures, 1249b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache final boolean expectActivityLaunch, final Bundle optionsIn) { 125056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 125156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "addAccount: accountType " + accountType 125256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", response " + response 125356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", authTokenType " + authTokenType 125456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", requiredFeatures " + stringArrayToString(requiredFeatures) 125556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", expectActivityLaunch " + expectActivityLaunch 125656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 125756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 125856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 1259382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (response == null) throw new IllegalArgumentException("response is null"); 1260382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (accountType == null) throw new IllegalArgumentException("accountType is null"); 1261d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkManageAccountsPermission(); 1262b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache 126304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 1264b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache final int pid = Binder.getCallingPid(); 1265b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache final int uid = Binder.getCallingUid(); 1266b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache final Bundle options = (optionsIn == null) ? new Bundle() : optionsIn; 1267b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache options.putInt(AccountManager.KEY_CALLER_UID, uid); 1268b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache options.putInt(AccountManager.KEY_CALLER_PID, pid); 1269b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache 127026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 127126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 127204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani new Session(accounts, response, accountType, expectActivityLaunch, 12738570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana true /* stripAuthTokenFromResult */) { 127426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana public void run() throws RemoteException { 12753348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache mAuthenticator.addAccount(this, mAccountType, authTokenType, requiredFeatures, 12763326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana options); 127726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1278a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 127926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana protected String toDebugString(long now) { 128026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana return super.toDebugString(now) + ", addAccount" 12813326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + ", accountType " + accountType 12823326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + ", requiredFeatures " 12833326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + (requiredFeatures != null 12843326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana ? TextUtils.join(",", requiredFeatures) 12853326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana : null); 128626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 128726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana }.bind(); 128826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 128926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 129026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1291603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1292603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1293a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void confirmCredentials(IAccountManagerResponse response, 1294f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana final Account account, final Bundle options, final boolean expectActivityLaunch) { 129556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 129656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "confirmCredentials: " + account 129756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", response " + response 129856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", expectActivityLaunch " + expectActivityLaunch 129956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 130056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 130156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 1302382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (response == null) throw new IllegalArgumentException("response is null"); 1303382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 1304d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkManageAccountsPermission(); 130504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 130626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 130726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 130804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani new Session(accounts, response, account.type, expectActivityLaunch, 13098570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana true /* stripAuthTokenFromResult */) { 131026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana public void run() throws RemoteException { 1311f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana mAuthenticator.confirmCredentials(this, account, options); 131226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 131326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana protected String toDebugString(long now) { 131426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana return super.toDebugString(now) + ", confirmCredentials" 131526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana + ", " + account; 131626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 131726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana }.bind(); 131826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 131926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 132026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1321603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1322603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1323a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void updateCredentials(IAccountManagerResponse response, final Account account, 1324a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana final String authTokenType, final boolean expectActivityLaunch, 1325a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana final Bundle loginOptions) { 132656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 132756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "updateCredentials: " + account 132856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", response " + response 132956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", authTokenType " + authTokenType 133056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", expectActivityLaunch " + expectActivityLaunch 133156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 133256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 133356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 1334382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (response == null) throw new IllegalArgumentException("response is null"); 1335382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 1336382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null"); 1337d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkManageAccountsPermission(); 133804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 133926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 134026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 134104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani new Session(accounts, response, account.type, expectActivityLaunch, 13428570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana true /* stripAuthTokenFromResult */) { 134326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana public void run() throws RemoteException { 134426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana mAuthenticator.updateCredentials(this, account, authTokenType, loginOptions); 134526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 134626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana protected String toDebugString(long now) { 134726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana if (loginOptions != null) loginOptions.keySet(); 134826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana return super.toDebugString(now) + ", updateCredentials" 134926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana + ", " + account 135026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana + ", authTokenType " + authTokenType 135126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana + ", loginOptions " + loginOptions; 135226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 135326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana }.bind(); 135426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 135526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 135626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1357603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1358603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1359a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void editProperties(IAccountManagerResponse response, final String accountType, 1360a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana final boolean expectActivityLaunch) { 136156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 136256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "editProperties: accountType " + accountType 136356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", response " + response 136456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", expectActivityLaunch " + expectActivityLaunch 136556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 136656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 136756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 1368382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (response == null) throw new IllegalArgumentException("response is null"); 1369382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (accountType == null) throw new IllegalArgumentException("accountType is null"); 1370d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkManageAccountsPermission(); 137104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 137226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 137326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 137404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani new Session(accounts, response, accountType, expectActivityLaunch, 13758570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana true /* stripAuthTokenFromResult */) { 137626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana public void run() throws RemoteException { 137726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana mAuthenticator.editProperties(this, mAccountType); 137826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 137926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana protected String toDebugString(long now) { 138026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana return super.toDebugString(now) + ", editProperties" 138126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana + ", accountType " + accountType; 138226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 138326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana }.bind(); 138426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 138526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 138626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1387603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1388603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 13893326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana private class GetAccountsByTypeAndFeatureSession extends Session { 13903326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana private final String[] mFeatures; 13913326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana private volatile Account[] mAccountsOfType = null; 13923326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana private volatile ArrayList<Account> mAccountsWithFeatures = null; 13933326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana private volatile int mCurrentAccount = 0; 13943326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 139504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani public GetAccountsByTypeAndFeatureSession(UserAccounts accounts, 139604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani IAccountManagerResponse response, String type, String[] features) { 139704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani super(accounts, response, type, false /* expectActivityLaunch */, 13988570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana true /* stripAuthTokenFromResult */); 13993326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana mFeatures = features; 14003326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 14013326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 14023326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana public void run() throws RemoteException { 140304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (mAccounts.cacheLock) { 140404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani mAccountsOfType = getAccountsFromCacheLocked(mAccounts, mAccountType); 1405f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 14063326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana // check whether each account matches the requested features 14073326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana mAccountsWithFeatures = new ArrayList<Account>(mAccountsOfType.length); 14083326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana mCurrentAccount = 0; 14093326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 14103326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana checkAccount(); 14113326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 14123326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 14133326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana public void checkAccount() { 14143326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana if (mCurrentAccount >= mAccountsOfType.length) { 14153326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana sendResult(); 14163326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana return; 14173326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 14183326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 141929e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana final IAccountAuthenticator accountAuthenticator = mAuthenticator; 142029e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana if (accountAuthenticator == null) { 142129e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana // It is possible that the authenticator has died, which is indicated by 142229e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana // mAuthenticator being set to null. If this happens then just abort. 142329e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana // There is no need to send back a result or error in this case since 142429e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana // that already happened when mAuthenticator was cleared. 142529e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 142629e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana Log.v(TAG, "checkAccount: aborting session since we are no longer" 142729e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana + " connected to the authenticator, " + toDebugString()); 142829e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana } 142929e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana return; 143029e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana } 14313326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana try { 143229e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana accountAuthenticator.hasFeatures(this, mAccountsOfType[mCurrentAccount], mFeatures); 14333326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } catch (RemoteException e) { 1434f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana onError(AccountManager.ERROR_CODE_REMOTE_EXCEPTION, "remote exception"); 1435a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1436603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1437603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 14383326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana public void onResult(Bundle result) { 14393326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana mNumResults++; 14403326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana if (result == null) { 1441f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana onError(AccountManager.ERROR_CODE_INVALID_RESPONSE, "null bundle"); 14423326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana return; 14433326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 1444f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana if (result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT, false)) { 14453326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana mAccountsWithFeatures.add(mAccountsOfType[mCurrentAccount]); 14463326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 14473326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana mCurrentAccount++; 14483326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana checkAccount(); 1449a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 14503326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 14513326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana public void sendResult() { 14523326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana IAccountManagerResponse response = getResponseAndClose(); 14533326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana if (response != null) { 14543326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana try { 14553326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana Account[] accounts = new Account[mAccountsWithFeatures.size()]; 14563326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana for (int i = 0; i < accounts.length; i++) { 14573326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana accounts[i] = mAccountsWithFeatures.get(i); 14583326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 145956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 146056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, getClass().getSimpleName() + " calling onResult() on response " 146156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + response); 146256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 14633326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana Bundle result = new Bundle(); 1464f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana result.putParcelableArray(AccountManager.KEY_ACCOUNTS, accounts); 14653326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana response.onResult(result); 14663326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } catch (RemoteException e) { 14673326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana // if the caller is dead then there is no one to care about remote exceptions 14683326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 14693326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana Log.v(TAG, "failure while notifying response", e); 14703326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 14713326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 14723326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 14733326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 14743326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 14753326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 14763326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana protected String toDebugString(long now) { 14773326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana return super.toDebugString(now) + ", getAccountsByTypeAndFeatures" 14783326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + ", " + (mFeatures != null ? TextUtils.join(",", mFeatures) : null); 14793326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 14803326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 1481ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 148204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani /** 148304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani * Returns the accounts for a specific user 148404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani * @hide 148504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani */ 148604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani public Account[] getAccounts(int userId) { 148704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani checkReadAccountsPermission(); 148804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccounts(userId); 148904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani long identityToken = clearCallingIdentity(); 149004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani try { 149104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 149204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani return getAccountsFromCacheLocked(accounts, null); 149304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 149404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } finally { 149504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani restoreCallingIdentity(identityToken); 149604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 149704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 149804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani 1499f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani /** 1500f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani * Returns all the accounts qualified by user. 1501f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani * @hide 1502f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani */ 1503f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani public AccountAndUser[] getAllAccounts() { 1504f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani ArrayList<AccountAndUser> allAccounts = new ArrayList<AccountAndUser>(); 1505f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani List<UserInfo> users = getAllUsers(); 1506f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani if (users == null) return new AccountAndUser[0]; 1507f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani 1508f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani synchronized(mUsers) { 1509f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani for (UserInfo user : users) { 1510f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani UserAccounts userAccounts = getUserAccounts(user.id); 1511f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani if (userAccounts == null) continue; 1512f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani synchronized (userAccounts.cacheLock) { 1513f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani Account[] accounts = getAccountsFromCacheLocked(userAccounts, null); 1514f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani for (int a = 0; a < accounts.length; a++) { 1515f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani allAccounts.add(new AccountAndUser(accounts[a], user.id)); 1516f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani } 1517f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani } 1518f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani } 1519f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani } 1520f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani AccountAndUser[] accountsArray = new AccountAndUser[allAccounts.size()]; 1521f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani return allAccounts.toArray(accountsArray); 1522f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani } 1523f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani 1524ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana public Account[] getAccounts(String type) { 152556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 152656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "getAccounts: accountType " + type 152756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 152856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 152956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 1530ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana checkReadAccountsPermission(); 153104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 1532ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana long identityToken = clearCallingIdentity(); 1533ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana try { 153404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 153504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani return getAccountsFromCacheLocked(accounts, type); 1536f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 1537ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } finally { 1538ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana restoreCallingIdentity(identityToken); 1539ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 1540ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 1541ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 1542ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana public void getAccountsByFeatures(IAccountManagerResponse response, 15433326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana String type, String[] features) { 154456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 154556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "getAccounts: accountType " + type 154656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", response " + response 154756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", features " + stringArrayToString(features) 154856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 154956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 155056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 1551382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (response == null) throw new IllegalArgumentException("response is null"); 1552382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (type == null) throw new IllegalArgumentException("accountType is null"); 1553d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkReadAccountsPermission(); 155404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts userAccounts = getUserAccountsForCaller(); 15553326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana long identityToken = clearCallingIdentity(); 15563326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana try { 1557ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana if (features == null || features.length == 0) { 1558f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana Account[] accounts; 155904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (userAccounts.cacheLock) { 156004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts = getAccountsFromCacheLocked(userAccounts, type); 1561f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 1562d4a9d6c42bb412e27a8383aaacd051419d98a662Fred Quintana Bundle result = new Bundle(); 1563d4a9d6c42bb412e27a8383aaacd051419d98a662Fred Quintana result.putParcelableArray(AccountManager.KEY_ACCOUNTS, accounts); 1564d4a9d6c42bb412e27a8383aaacd051419d98a662Fred Quintana onResult(response, result); 1565ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana return; 1566ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 156704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani new GetAccountsByTypeAndFeatureSession(userAccounts, response, type, features).bind(); 15683326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } finally { 15693326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana restoreCallingIdentity(identityToken); 15703326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 15713326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 15723326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 1573f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana private long getAccountIdLocked(SQLiteDatabase db, Account account) { 1574603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana Cursor cursor = db.query(TABLE_ACCOUNTS, new String[]{ACCOUNTS_ID}, 1575ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana "name=? AND type=?", new String[]{account.name, account.type}, null, null, null); 1576603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana try { 1577603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana if (cursor.moveToNext()) { 1578603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana return cursor.getLong(0); 1579603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1580603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana return -1; 1581603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } finally { 1582603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana cursor.close(); 1583603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1584603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1585603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1586f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana private long getExtrasIdLocked(SQLiteDatabase db, long accountId, String key) { 1587603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana Cursor cursor = db.query(TABLE_EXTRAS, new String[]{EXTRAS_ID}, 1588603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana EXTRAS_ACCOUNTS_ID + "=" + accountId + " AND " + EXTRAS_KEY + "=?", 1589603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana new String[]{key}, null, null, null); 1590603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana try { 1591603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana if (cursor.moveToNext()) { 1592603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana return cursor.getLong(0); 1593603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1594603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana return -1; 1595603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } finally { 1596603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana cursor.close(); 1597603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1598603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1599603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1600a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana private abstract class Session extends IAccountAuthenticatorResponse.Stub 1601b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana implements IBinder.DeathRecipient, ServiceConnection { 1602603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana IAccountManagerResponse mResponse; 1603603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana final String mAccountType; 1604a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana final boolean mExpectActivityLaunch; 1605a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana final long mCreationTime; 1606a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 16073326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana public int mNumResults = 0; 1608a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana private int mNumRequestContinued = 0; 1609a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana private int mNumErrors = 0; 1610a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 1611603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1612603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana IAccountAuthenticator mAuthenticator = null; 1613603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 16148570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana private final boolean mStripAuthTokenFromResult; 161504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani protected final UserAccounts mAccounts; 16168570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana 161704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani public Session(UserAccounts accounts, IAccountManagerResponse response, String accountType, 16188570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana boolean expectActivityLaunch, boolean stripAuthTokenFromResult) { 1619603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana super(); 1620a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (response == null) throw new IllegalArgumentException("response is null"); 16213326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana if (accountType == null) throw new IllegalArgumentException("accountType is null"); 162204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani mAccounts = accounts; 16238570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana mStripAuthTokenFromResult = stripAuthTokenFromResult; 1624603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mResponse = response; 1625603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mAccountType = accountType; 1626a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana mExpectActivityLaunch = expectActivityLaunch; 1627a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana mCreationTime = SystemClock.elapsedRealtime(); 1628a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana synchronized (mSessions) { 1629a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana mSessions.put(toString(), this); 1630a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1631a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana try { 1632a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana response.asBinder().linkToDeath(this, 0 /* flags */); 1633a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } catch (RemoteException e) { 1634a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana mResponse = null; 1635a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana binderDied(); 1636a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1637603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1638603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1639a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana IAccountManagerResponse getResponseAndClose() { 1640603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana if (mResponse == null) { 1641603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana // this session has already been closed 1642603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana return null; 1643603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1644a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana IAccountManagerResponse response = mResponse; 1645a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana close(); // this clears mResponse so we need to save the response before this call 1646a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana return response; 1647a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1648a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 1649a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana private void close() { 1650a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana synchronized (mSessions) { 1651a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (mSessions.remove(toString()) == null) { 1652a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana // the session was already closed, so bail out now 1653a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana return; 1654a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1655a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1656a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (mResponse != null) { 1657a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana // stop listening for response deaths 1658a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana mResponse.asBinder().unlinkToDeath(this, 0 /* flags */); 1659a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 1660a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana // clear this so that we don't accidentally send any further results 1661a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana mResponse = null; 1662a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1663603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana cancelTimeout(); 1664603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana unbind(); 1665a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1666a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 1667a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void binderDied() { 1668603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mResponse = null; 1669a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana close(); 1670a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1671a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 1672a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana protected String toDebugString() { 1673a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana return toDebugString(SystemClock.elapsedRealtime()); 1674a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1675a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 1676a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana protected String toDebugString(long now) { 1677a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana return "Session: expectLaunch " + mExpectActivityLaunch 1678a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + ", connected " + (mAuthenticator != null) 1679a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + ", stats (" + mNumResults + "/" + mNumRequestContinued 1680a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + "/" + mNumErrors + ")" 1681a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + ", lifetime " + ((now - mCreationTime) / 1000.0); 1682603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1683603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1684603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana void bind() { 1685a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 1686a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana Log.v(TAG, "initiating bind to authenticator type " + mAccountType); 1687a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1688b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana if (!bindToAuthenticator(mAccountType)) { 1689a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana Log.d(TAG, "bind attempt failed for " + toDebugString()); 1690f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana onError(AccountManager.ERROR_CODE_REMOTE_EXCEPTION, "bind failure"); 1691603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1692603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1693603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1694603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private void unbind() { 1695603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana if (mAuthenticator != null) { 1696603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mAuthenticator = null; 1697b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana mContext.unbindService(this); 1698603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1699603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1700603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1701603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public void scheduleTimeout() { 1702603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mMessageHandler.sendMessageDelayed( 1703603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mMessageHandler.obtainMessage(MESSAGE_TIMED_OUT, this), TIMEOUT_DELAY_MS); 1704603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1705603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1706603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public void cancelTimeout() { 1707603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mMessageHandler.removeMessages(MESSAGE_TIMED_OUT, this); 1708603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1709603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1710b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana public void onServiceConnected(ComponentName name, IBinder service) { 1711603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mAuthenticator = IAccountAuthenticator.Stub.asInterface(service); 1712a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana try { 1713a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana run(); 1714a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } catch (RemoteException e) { 1715f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana onError(AccountManager.ERROR_CODE_REMOTE_EXCEPTION, 1716a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana "remote exception"); 1717a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1718603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1719603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1720b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana public void onServiceDisconnected(ComponentName name) { 1721a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana mAuthenticator = null; 1722a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana IAccountManagerResponse response = getResponseAndClose(); 1723603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana if (response != null) { 1724166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana try { 1725166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana response.onError(AccountManager.ERROR_CODE_REMOTE_EXCEPTION, 1726166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana "disconnected"); 1727166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana } catch (RemoteException e) { 1728166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 1729166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana Log.v(TAG, "Session.onServiceDisconnected: " 1730166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana + "caught RemoteException while responding", e); 1731166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana } 1732166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana } 1733603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1734603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1735603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1736b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana public abstract void run() throws RemoteException; 1737b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana 1738603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public void onTimedOut() { 1739a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana IAccountManagerResponse response = getResponseAndClose(); 1740603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana if (response != null) { 1741166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana try { 1742166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana response.onError(AccountManager.ERROR_CODE_REMOTE_EXCEPTION, 1743166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana "timeout"); 1744166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana } catch (RemoteException e) { 1745166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 1746166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana Log.v(TAG, "Session.onTimedOut: caught RemoteException while responding", 1747166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana e); 1748166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana } 1749166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana } 1750603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1751603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1752603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1753a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void onResult(Bundle result) { 1754a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana mNumResults++; 1755f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana if (result != null && !TextUtils.isEmpty(result.getString(AccountManager.KEY_AUTHTOKEN))) { 1756f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana String accountName = result.getString(AccountManager.KEY_ACCOUNT_NAME); 1757f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana String accountType = result.getString(AccountManager.KEY_ACCOUNT_TYPE); 1758d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (!TextUtils.isEmpty(accountName) && !TextUtils.isEmpty(accountType)) { 1759d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Account account = new Account(accountName, accountType); 176004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani cancelNotification(getSigninRequiredNotificationId(mAccounts, account)); 1761d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1762603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1763a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana IAccountManagerResponse response; 1764a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (mExpectActivityLaunch && result != null 1765f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana && result.containsKey(AccountManager.KEY_INTENT)) { 1766a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana response = mResponse; 1767a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } else { 1768a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana response = getResponseAndClose(); 1769603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1770603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana if (response != null) { 1771603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana try { 1772a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (result == null) { 177356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 177456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, getClass().getSimpleName() 177556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + " calling onError() on response " + response); 177656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 1777f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana response.onError(AccountManager.ERROR_CODE_INVALID_RESPONSE, 1778a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana "null bundle returned"); 1779a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } else { 17808570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana if (mStripAuthTokenFromResult) { 17818570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana result.remove(AccountManager.KEY_AUTHTOKEN); 17828570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana } 178356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 178456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, getClass().getSimpleName() 178556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + " calling onResult() on response " + response); 178656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 1787a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana response.onResult(result); 1788a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1789603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } catch (RemoteException e) { 1790a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana // if the caller is dead then there is no one to care about remote exceptions 1791a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 1792a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana Log.v(TAG, "failure while notifying response", e); 1793a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1794603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1795603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1796603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1797603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1798a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void onRequestContinued() { 1799a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana mNumRequestContinued++; 1800603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1801603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1802603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public void onError(int errorCode, String errorMessage) { 1803a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana mNumErrors++; 1804a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana IAccountManagerResponse response = getResponseAndClose(); 1805a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (response != null) { 1806a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 180756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, getClass().getSimpleName() 180856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + " calling onError() on response " + response); 1809a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1810a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana try { 1811a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana response.onError(errorCode, errorMessage); 1812a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } catch (RemoteException e) { 1813a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 1814a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana Log.v(TAG, "Session.onError: caught RemoteException while responding", e); 1815a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1816a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1817a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } else { 1818a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 1819a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana Log.v(TAG, "Session.onError: already closed"); 1820a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1821603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1822603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1823b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana 1824b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana /** 1825b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana * find the component name for the authenticator and initiate a bind 1826b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana * if no authenticator or the bind fails then return false, otherwise return true 1827b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana */ 1828b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana private boolean bindToAuthenticator(String authenticatorType) { 1829b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana AccountAuthenticatorCache.ServiceInfo<AuthenticatorDescription> authenticatorInfo = 1830b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana mAuthenticatorCache.getServiceInfo( 1831b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana AuthenticatorDescription.newKey(authenticatorType)); 1832b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana if (authenticatorInfo == null) { 1833b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 1834b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana Log.v(TAG, "there is no authenticator for " + authenticatorType 1835b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana + ", bailing out"); 1836b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana } 1837b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana return false; 1838b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana } 1839b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana 1840b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana Intent intent = new Intent(); 1841b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana intent.setAction(AccountManager.ACTION_AUTHENTICATOR_INTENT); 1842b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana intent.setComponent(authenticatorInfo.componentName); 1843b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 1844b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana Log.v(TAG, "performing bindService to " + authenticatorInfo.componentName); 1845b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana } 184634daa75260c9aebe791819ff6134b4c47146c5c0Amith Yamasani if (!mContext.bindService(intent, this, Context.BIND_AUTO_CREATE, mAccounts.userId)) { 1847b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 1848b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana Log.v(TAG, "bindService to " + authenticatorInfo.componentName + " failed"); 1849b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana } 1850b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana return false; 1851b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana } 1852b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana 1853b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana 1854b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana return true; 1855b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana } 1856603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1857603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1858603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private class MessageHandler extends Handler { 1859603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana MessageHandler(Looper looper) { 1860603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana super(looper); 1861603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 18623348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache 1863603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public void handleMessage(Message msg) { 1864603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana switch (msg.what) { 1865603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana case MESSAGE_TIMED_OUT: 1866603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana Session session = (Session)msg.obj; 1867603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana session.onTimedOut(); 1868603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana break; 1869603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1870603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana default: 1871603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana throw new IllegalStateException("unhandled message: " + msg.what); 1872603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1873603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1874603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1875603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 187604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private static String getDatabaseName(int userId) { 187704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani File systemDir = Environment.getSystemSecureDirectory(); 187804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani File databaseFile = new File(systemDir, "users/" + userId + "/" + DATABASE_NAME); 187904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani if (userId == 0) { 1880a23bb38628ac1f5dc4ebe6847faedc424dd5fce1Amith Yamasani // Migrate old file, if it exists, to the new location. 1881a23bb38628ac1f5dc4ebe6847faedc424dd5fce1Amith Yamasani // Make sure the new file doesn't already exist. A dummy file could have been 1882a23bb38628ac1f5dc4ebe6847faedc424dd5fce1Amith Yamasani // accidentally created in the old location, causing the new one to become corrupted 1883a23bb38628ac1f5dc4ebe6847faedc424dd5fce1Amith Yamasani // as well. 188404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani File oldFile = new File(systemDir, DATABASE_NAME); 1885a23bb38628ac1f5dc4ebe6847faedc424dd5fce1Amith Yamasani if (oldFile.exists() && !databaseFile.exists()) { 1886c6b0f99bb31405902b40a96f6491a9adcaaac169Marc Blank // Check for use directory; create if it doesn't exist, else renameTo will fail 1887c6b0f99bb31405902b40a96f6491a9adcaaac169Marc Blank File userDir = new File(systemDir, "users/" + userId); 1888c6b0f99bb31405902b40a96f6491a9adcaaac169Marc Blank if (!userDir.exists()) { 1889c6b0f99bb31405902b40a96f6491a9adcaaac169Marc Blank if (!userDir.mkdirs()) { 1890c6b0f99bb31405902b40a96f6491a9adcaaac169Marc Blank throw new IllegalStateException("User dir cannot be created: " + userDir); 1891c6b0f99bb31405902b40a96f6491a9adcaaac169Marc Blank } 1892c6b0f99bb31405902b40a96f6491a9adcaaac169Marc Blank } 1893c6b0f99bb31405902b40a96f6491a9adcaaac169Marc Blank if (!oldFile.renameTo(databaseFile)) { 1894c6b0f99bb31405902b40a96f6491a9adcaaac169Marc Blank throw new IllegalStateException("User dir cannot be migrated: " + databaseFile); 1895c6b0f99bb31405902b40a96f6491a9adcaaac169Marc Blank } 189604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 1897a8529f68671a8a118751cb6ad577f44eaf076b96Oscar Montemayor } 189804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani return databaseFile.getPath(); 1899a8529f68671a8a118751cb6ad577f44eaf076b96Oscar Montemayor } 1900a8529f68671a8a118751cb6ad577f44eaf076b96Oscar Montemayor 190104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani static class DatabaseHelper extends SQLiteOpenHelper { 1902a8529f68671a8a118751cb6ad577f44eaf076b96Oscar Montemayor 190304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani public DatabaseHelper(Context context, int userId) { 190404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani super(context, AccountManagerService.getDatabaseName(userId), null, DATABASE_VERSION); 1905603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1906603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1907f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana /** 1908f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana * This call needs to be made while the mCacheLock is held. The way to 1909f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana * ensure this is to get the lock any time a method is called ont the DatabaseHelper 1910f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana * @param db The database. 1911f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana */ 1912603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana @Override 1913603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public void onCreate(SQLiteDatabase db) { 1914603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana db.execSQL("CREATE TABLE " + TABLE_ACCOUNTS + " ( " 1915603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + ACCOUNTS_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " 1916603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + ACCOUNTS_NAME + " TEXT NOT NULL, " 1917603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + ACCOUNTS_TYPE + " TEXT NOT NULL, " 1918603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + ACCOUNTS_PASSWORD + " TEXT, " 1919603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + "UNIQUE(" + ACCOUNTS_NAME + "," + ACCOUNTS_TYPE + "))"); 1920603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1921603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana db.execSQL("CREATE TABLE " + TABLE_AUTHTOKENS + " ( " 1922603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + AUTHTOKENS_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " 1923603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + AUTHTOKENS_ACCOUNTS_ID + " INTEGER NOT NULL, " 1924603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + AUTHTOKENS_TYPE + " TEXT NOT NULL, " 1925603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + AUTHTOKENS_AUTHTOKEN + " TEXT, " 1926603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + "UNIQUE (" + AUTHTOKENS_ACCOUNTS_ID + "," + AUTHTOKENS_TYPE + "))"); 1927603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1928d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana createGrantsTable(db); 1929d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 1930603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana db.execSQL("CREATE TABLE " + TABLE_EXTRAS + " ( " 1931603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + EXTRAS_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " 1932603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + EXTRAS_ACCOUNTS_ID + " INTEGER, " 1933603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + EXTRAS_KEY + " TEXT NOT NULL, " 1934603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + EXTRAS_VALUE + " TEXT, " 1935603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + "UNIQUE(" + EXTRAS_ACCOUNTS_ID + "," + EXTRAS_KEY + "))"); 1936603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1937603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana db.execSQL("CREATE TABLE " + TABLE_META + " ( " 1938603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + META_KEY + " TEXT PRIMARY KEY NOT NULL, " 1939603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + META_VALUE + " TEXT)"); 1940a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 1941d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana createAccountsDeletionTrigger(db); 1942d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1943d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 1944d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private void createAccountsDeletionTrigger(SQLiteDatabase db) { 1945a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana db.execSQL("" 1946a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + " CREATE TRIGGER " + TABLE_ACCOUNTS + "Delete DELETE ON " + TABLE_ACCOUNTS 1947a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + " BEGIN" 1948a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + " DELETE FROM " + TABLE_AUTHTOKENS 1949a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + " WHERE " + AUTHTOKENS_ACCOUNTS_ID + "=OLD." + ACCOUNTS_ID + " ;" 1950a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + " DELETE FROM " + TABLE_EXTRAS 1951a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + " WHERE " + EXTRAS_ACCOUNTS_ID + "=OLD." + ACCOUNTS_ID + " ;" 1952d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + " DELETE FROM " + TABLE_GRANTS 1953d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + " WHERE " + GRANTS_ACCOUNTS_ID + "=OLD." + ACCOUNTS_ID + " ;" 1954a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + " END"); 1955603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1956603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1957d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private void createGrantsTable(SQLiteDatabase db) { 1958d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana db.execSQL("CREATE TABLE " + TABLE_GRANTS + " ( " 1959d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + GRANTS_ACCOUNTS_ID + " INTEGER NOT NULL, " 1960d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + GRANTS_AUTH_TOKEN_TYPE + " STRING NOT NULL, " 1961d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + GRANTS_GRANTEE_UID + " INTEGER NOT NULL, " 1962d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + "UNIQUE (" + GRANTS_ACCOUNTS_ID + "," + GRANTS_AUTH_TOKEN_TYPE 1963d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + "," + GRANTS_GRANTEE_UID + "))"); 1964d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1965d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 1966603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana @Override 1967603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 1968a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana Log.e(TAG, "upgrade from version " + oldVersion + " to version " + newVersion); 1969603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1970a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (oldVersion == 1) { 1971d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana // no longer need to do anything since the work is done 1972d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana // when upgrading from version 2 1973d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana oldVersion++; 1974d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1975d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 1976d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (oldVersion == 2) { 1977d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana createGrantsTable(db); 1978d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana db.execSQL("DROP TRIGGER " + TABLE_ACCOUNTS + "Delete"); 1979d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana createAccountsDeletionTrigger(db); 1980a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana oldVersion++; 1981a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 19823348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache 19833348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache if (oldVersion == 3) { 19843348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache db.execSQL("UPDATE " + TABLE_ACCOUNTS + " SET " + ACCOUNTS_TYPE + 19853348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache " = 'com.google' WHERE " + ACCOUNTS_TYPE + " == 'com.google.GAIA'"); 19863348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache oldVersion++; 19873348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache } 1988603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1989603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1990603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana @Override 1991603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public void onOpen(SQLiteDatabase db) { 1992603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "opened database " + DATABASE_NAME); 1993603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1994603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1995603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1996603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public IBinder onBind(Intent intent) { 1997603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana return asBinder(); 1998603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1999a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 20001cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks /** 20011cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks * Searches array of arguments for the specified string 20021cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks * @param args array of argument strings 20031cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks * @param value value to search for 20041cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks * @return true if the value is contained in the array 20051cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks */ 20061cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks private static boolean scanArgs(String[] args, String value) { 20071cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks if (args != null) { 20081cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks for (String arg : args) { 20091cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks if (value.equals(arg)) { 20101cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks return true; 20111cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks } 2012a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 2013a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 20141cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks return false; 20151cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks } 2016a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 20171cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) { 20183abd75ba3a981850cac43a401d0014a836559cb0Kenny Root if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 20193abd75ba3a981850cac43a401d0014a836559cb0Kenny Root != PackageManager.PERMISSION_GRANTED) { 20203abd75ba3a981850cac43a401d0014a836559cb0Kenny Root fout.println("Permission Denial: can't dump AccountsManager from from pid=" 20213abd75ba3a981850cac43a401d0014a836559cb0Kenny Root + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 20223abd75ba3a981850cac43a401d0014a836559cb0Kenny Root + " without permission " + android.Manifest.permission.DUMP); 20233abd75ba3a981850cac43a401d0014a836559cb0Kenny Root return; 20243abd75ba3a981850cac43a401d0014a836559cb0Kenny Root } 202504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final boolean isCheckinRequest = scanArgs(args, "--checkin") || scanArgs(args, "-c"); 20263abd75ba3a981850cac43a401d0014a836559cb0Kenny Root 202704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani fout = new IndentingPrintWriter(fout, " "); 202804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani int size = mUsers.size(); 202904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani for (int i = 0; i < size; i++) { 203004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani fout.println("User " + mUsers.keyAt(i) + ":"); 203104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani ((IndentingPrintWriter) fout).increaseIndent(); 203204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani dumpUser(mUsers.valueAt(i), fd, fout, args, isCheckinRequest); 203304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani ((IndentingPrintWriter) fout).decreaseIndent(); 203404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani if (i < size - 1) { 203504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani fout.println(); 203604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 203704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 203804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 20391cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks 204004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private void dumpUser(UserAccounts userAccounts, FileDescriptor fd, PrintWriter fout, 204104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani String[] args, boolean isCheckinRequest) { 204204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (userAccounts.cacheLock) { 204304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = userAccounts.openHelper.getReadableDatabase(); 2044a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 2045f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (isCheckinRequest) { 2046f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana // This is a checkin request. *Only* upload the account types and the count of each. 2047f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana Cursor cursor = db.query(TABLE_ACCOUNTS, ACCOUNT_TYPE_COUNT_PROJECTION, 2048f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana null, null, ACCOUNTS_TYPE, null, null); 2049f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana try { 2050f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana while (cursor.moveToNext()) { 2051f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana // print type,count 2052f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana fout.println(cursor.getString(0) + "," + cursor.getString(1)); 2053f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 2054f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } finally { 2055f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (cursor != null) { 2056f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana cursor.close(); 2057f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 20581cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks } 2059f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } else { 206004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani Account[] accounts = getAccountsFromCacheLocked(userAccounts, null /* type */); 2061f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana fout.println("Accounts: " + accounts.length); 2062f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana for (Account account : accounts) { 2063f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana fout.println(" " + account); 20641cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks } 2065307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana 2066f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana fout.println(); 2067f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana synchronized (mSessions) { 2068f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana final long now = SystemClock.elapsedRealtime(); 2069f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana fout.println("Active Sessions: " + mSessions.size()); 2070f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana for (Session session : mSessions.values()) { 2071f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana fout.println(" " + session.toDebugString(now)); 2072f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 20731cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks } 20741cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks 2075f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana fout.println(); 2076f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana mAuthenticatorCache.dump(fd, fout, args); 2077f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 20781cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks } 2079a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 2080a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 208104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private void doNotification(UserAccounts accounts, Account account, CharSequence message, 208204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani Intent intent) { 208326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 208426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 208526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 208626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana Log.v(TAG, "doNotification: " + message + " intent:" + intent); 208726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 2088a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 2089d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (intent.getComponent() != null && 2090d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana GrantCredentialsPermissionActivity.class.getName().equals( 2091d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana intent.getComponent().getClassName())) { 2092d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana createNoCredentialsPermissionNotification(account, intent); 2093d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } else { 209404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final Integer notificationId = getSigninRequiredNotificationId(accounts, account); 209533f889ae270f888f8fdc084f5f1f3d443532a46aFred Quintana intent.addCategory(String.valueOf(notificationId)); 2096d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Notification n = new Notification(android.R.drawable.stat_sys_warning, null, 2097d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 0 /* when */); 209833f889ae270f888f8fdc084f5f1f3d443532a46aFred Quintana final String notificationTitleFormat = 209933f889ae270f888f8fdc084f5f1f3d443532a46aFred Quintana mContext.getText(R.string.notification_title).toString(); 210033f889ae270f888f8fdc084f5f1f3d443532a46aFred Quintana n.setLatestEventInfo(mContext, 210133f889ae270f888f8fdc084f5f1f3d443532a46aFred Quintana String.format(notificationTitleFormat, account.name), 2102d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana message, PendingIntent.getActivity( 2103d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana mContext, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT)); 210456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana installNotification(notificationId, n); 2105d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 210626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 210726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 210826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 2109a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 2110a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 211156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana protected void installNotification(final int notificationId, final Notification n) { 211256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana ((NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE)) 211356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana .notify(notificationId, n); 211456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 211556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 211656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana protected void cancelNotification(int id) { 211726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 211826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 211926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana ((NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE)) 2120d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana .cancel(id); 212126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 212226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 212326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 2124a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 2125d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 2126b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana /** Succeeds if any of the specified permissions are granted. */ 2127b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana private void checkBinderPermission(String... permissions) { 2128d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana final int uid = Binder.getCallingUid(); 2129b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana 2130b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana for (String perm : permissions) { 2131b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana if (mContext.checkCallingOrSelfPermission(perm) == PackageManager.PERMISSION_GRANTED) { 2132b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 213356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, " caller uid " + uid + " has " + perm); 2134b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana } 2135b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana return; 2136b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana } 2137d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2138b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana 2139b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana String msg = "caller uid " + uid + " lacks any of " + TextUtils.join(",", permissions); 214056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.w(TAG, " " + msg); 2141b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana throw new SecurityException(msg); 2142d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2143d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 21447be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana private boolean inSystemImage(int callerUid) { 214556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana String[] packages = mPackageManager.getPackagesForUid(callerUid); 21467be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana for (String name : packages) { 21477be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana try { 214856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana PackageInfo packageInfo = mPackageManager.getPackageInfo(name, 0 /* flags */); 214956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (packageInfo != null 215056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana && (packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 21517be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana return true; 21527be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana } 21537be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana } catch (PackageManager.NameNotFoundException e) { 21547be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana return false; 21557be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana } 21567be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana } 21577be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana return false; 21587be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana } 21597be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana 2160d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private boolean permissionIsGranted(Account account, String authTokenType, int callerUid) { 2161b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana final boolean inSystemImage = inSystemImage(callerUid); 216231957f1badbb900bbfe211317e1ea992d650a72dFred Quintana final boolean fromAuthenticator = account != null 216331957f1badbb900bbfe211317e1ea992d650a72dFred Quintana && hasAuthenticatorUid(account.type, callerUid); 216431957f1badbb900bbfe211317e1ea992d650a72dFred Quintana final boolean hasExplicitGrants = account != null 216504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani && hasExplicitlyGrantedPermission(account, authTokenType, callerUid); 2166d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 2167d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Log.v(TAG, "checkGrantsOrCallingUidAgainstAuthenticator: caller uid " 216856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + callerUid + ", " + account 2169d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + ": is authenticator? " + fromAuthenticator 2170d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + ", has explicit permission? " + hasExplicitGrants); 2171d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2172b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana return fromAuthenticator || hasExplicitGrants || inSystemImage; 2173d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2174d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 21751a23191bbde11505d6e0c25c04a60b41cb27fd31Fred Quintana private boolean hasAuthenticatorUid(String accountType, int callingUid) { 2176d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana for (RegisteredServicesCache.ServiceInfo<AuthenticatorDescription> serviceInfo : 2177d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana mAuthenticatorCache.getAllServices()) { 2178d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (serviceInfo.type.type.equals(accountType)) { 2179ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana return (serviceInfo.uid == callingUid) || 218056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana (mPackageManager.checkSignatures(serviceInfo.uid, callingUid) 2181ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana == PackageManager.SIGNATURE_MATCH); 2182d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2183d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2184d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana return false; 2185d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2186d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 218704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private boolean hasExplicitlyGrantedPermission(Account account, String authTokenType, 218804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani int callerUid) { 218904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani if (callerUid == android.os.Process.SYSTEM_UID) { 2190d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana return true; 2191d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 219204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 219304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 219404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getReadableDatabase(); 219504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani String[] args = { String.valueOf(callerUid), authTokenType, 2196f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana account.name, account.type}; 2197f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana final boolean permissionGranted = 2198f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana DatabaseUtils.longForQuery(db, COUNT_OF_MATCHING_GRANTS, args) != 0; 2199f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (!permissionGranted && ActivityManager.isRunningInTestHarness()) { 2200f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana // TODO: Skip this check when running automated tests. Replace this 2201f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana // with a more general solution. 2202f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana Log.d(TAG, "no credentials permission for usage of " + account + ", " 220304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani + authTokenType + " by uid " + callerUid 2204f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana + " but ignoring since device is in test harness."); 2205f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return true; 2206f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 2207f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return permissionGranted; 2208d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2209d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2210d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 2211d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private void checkCallingUidAgainstAuthenticator(Account account) { 2212d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana final int uid = Binder.getCallingUid(); 221331957f1badbb900bbfe211317e1ea992d650a72dFred Quintana if (account == null || !hasAuthenticatorUid(account.type, uid)) { 2214d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana String msg = "caller uid " + uid + " is different than the authenticator's uid"; 2215d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Log.w(TAG, msg); 2216d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana throw new SecurityException(msg); 2217d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2218d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 2219d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Log.v(TAG, "caller uid " + uid + " is the same as the authenticator's uid"); 2220d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2221d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2222d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 2223d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private void checkAuthenticateAccountsPermission(Account account) { 2224d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkBinderPermission(Manifest.permission.AUTHENTICATE_ACCOUNTS); 2225d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkCallingUidAgainstAuthenticator(account); 2226d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2227d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 2228d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private void checkReadAccountsPermission() { 2229d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkBinderPermission(Manifest.permission.GET_ACCOUNTS); 2230d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2231d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 2232d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private void checkManageAccountsPermission() { 2233d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkBinderPermission(Manifest.permission.MANAGE_ACCOUNTS); 2234d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2235d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 2236b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana private void checkManageAccountsOrUseCredentialsPermissions() { 2237b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana checkBinderPermission(Manifest.permission.MANAGE_ACCOUNTS, 2238b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana Manifest.permission.USE_CREDENTIALS); 2239b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana } 2240b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana 2241d9640ec712806508877868d08aafaa2d715ff441Fred Quintana public void updateAppPermission(Account account, String authTokenType, int uid, boolean value) 2242d9640ec712806508877868d08aafaa2d715ff441Fred Quintana throws RemoteException { 2243d9640ec712806508877868d08aafaa2d715ff441Fred Quintana final int callingUid = getCallingUid(); 2244d9640ec712806508877868d08aafaa2d715ff441Fred Quintana 2245d9640ec712806508877868d08aafaa2d715ff441Fred Quintana if (callingUid != android.os.Process.SYSTEM_UID) { 2246d9640ec712806508877868d08aafaa2d715ff441Fred Quintana throw new SecurityException(); 2247d9640ec712806508877868d08aafaa2d715ff441Fred Quintana } 2248d9640ec712806508877868d08aafaa2d715ff441Fred Quintana 2249d9640ec712806508877868d08aafaa2d715ff441Fred Quintana if (value) { 2250d9640ec712806508877868d08aafaa2d715ff441Fred Quintana grantAppPermission(account, authTokenType, uid); 2251d9640ec712806508877868d08aafaa2d715ff441Fred Quintana } else { 2252d9640ec712806508877868d08aafaa2d715ff441Fred Quintana revokeAppPermission(account, authTokenType, uid); 2253d9640ec712806508877868d08aafaa2d715ff441Fred Quintana } 2254d9640ec712806508877868d08aafaa2d715ff441Fred Quintana } 2255d9640ec712806508877868d08aafaa2d715ff441Fred Quintana 2256d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana /** 2257d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * Allow callers with the given uid permission to get credentials for account/authTokenType. 2258d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * <p> 2259d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * Although this is public it can only be accessed via the AccountManagerService object 2260d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * which is in the system. This means we don't need to protect it with permissions. 2261d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * @hide 2262d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana */ 2263d9640ec712806508877868d08aafaa2d715ff441Fred Quintana private void grantAppPermission(Account account, String authTokenType, int uid) { 2264382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null || authTokenType == null) { 2265382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana Log.e(TAG, "grantAppPermission: called with invalid arguments", new Exception()); 226631957f1badbb900bbfe211317e1ea992d650a72dFred Quintana return; 226731957f1badbb900bbfe211317e1ea992d650a72dFred Quintana } 226804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccounts(UserId.getUserId(uid)); 226904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 227004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getWritableDatabase(); 2271f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.beginTransaction(); 2272f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana try { 2273f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana long accountId = getAccountIdLocked(db, account); 2274f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (accountId >= 0) { 2275f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana ContentValues values = new ContentValues(); 2276f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana values.put(GRANTS_ACCOUNTS_ID, accountId); 2277f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana values.put(GRANTS_AUTH_TOKEN_TYPE, authTokenType); 2278f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana values.put(GRANTS_GRANTEE_UID, uid); 2279f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.insert(TABLE_GRANTS, GRANTS_ACCOUNTS_ID, values); 2280f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.setTransactionSuccessful(); 2281f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 2282f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } finally { 2283f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.endTransaction(); 2284d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2285f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana cancelNotification(getCredentialPermissionNotificationId(account, authTokenType, uid)); 2286d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2287d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2288d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 2289d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana /** 2290d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * Don't allow callers with the given uid permission to get credentials for 2291d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * account/authTokenType. 2292d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * <p> 2293d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * Although this is public it can only be accessed via the AccountManagerService object 2294d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * which is in the system. This means we don't need to protect it with permissions. 2295d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * @hide 2296d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana */ 2297d9640ec712806508877868d08aafaa2d715ff441Fred Quintana private void revokeAppPermission(Account account, String authTokenType, int uid) { 2298382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null || authTokenType == null) { 2299382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana Log.e(TAG, "revokeAppPermission: called with invalid arguments", new Exception()); 230031957f1badbb900bbfe211317e1ea992d650a72dFred Quintana return; 230131957f1badbb900bbfe211317e1ea992d650a72dFred Quintana } 230204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccounts(UserId.getUserId(uid)); 230304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 230404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getWritableDatabase(); 2305f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.beginTransaction(); 2306f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana try { 2307f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana long accountId = getAccountIdLocked(db, account); 2308f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (accountId >= 0) { 2309f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.delete(TABLE_GRANTS, 2310f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana GRANTS_ACCOUNTS_ID + "=? AND " + GRANTS_AUTH_TOKEN_TYPE + "=? AND " 2311f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana + GRANTS_GRANTEE_UID + "=?", 2312f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana new String[]{String.valueOf(accountId), authTokenType, 2313f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana String.valueOf(uid)}); 2314f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.setTransactionSuccessful(); 2315f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 2316f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } finally { 2317f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.endTransaction(); 2318d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2319f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana cancelNotification(getCredentialPermissionNotificationId(account, authTokenType, uid)); 2320d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2321d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 232256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 232356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana static final private String stringArrayToString(String[] value) { 232456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana return value != null ? ("[" + TextUtils.join(",", value) + "]") : null; 232556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 232656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 232704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private void removeAccountFromCacheLocked(UserAccounts accounts, Account account) { 232804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final Account[] oldAccountsForType = accounts.accountCache.get(account.type); 2329f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (oldAccountsForType != null) { 2330f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana ArrayList<Account> newAccountsList = new ArrayList<Account>(); 2331f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana for (Account curAccount : oldAccountsForType) { 2332f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (!curAccount.equals(account)) { 2333f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana newAccountsList.add(curAccount); 233456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 233556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 2336f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (newAccountsList.isEmpty()) { 233704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.accountCache.remove(account.type); 2338f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } else { 2339f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana Account[] newAccountsForType = new Account[newAccountsList.size()]; 2340f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana newAccountsForType = newAccountsList.toArray(newAccountsForType); 234104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.accountCache.put(account.type, newAccountsForType); 2342f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 234356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 234404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.userDataCache.remove(account); 234504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.authTokenCache.remove(account); 234656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 234756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 234856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana /** 234956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana * This assumes that the caller has already checked that the account is not already present. 235056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana */ 235104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private void insertAccountIntoCacheLocked(UserAccounts accounts, Account account) { 235204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani Account[] accountsForType = accounts.accountCache.get(account.type); 2353f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana int oldLength = (accountsForType != null) ? accountsForType.length : 0; 2354f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana Account[] newAccountsForType = new Account[oldLength + 1]; 2355f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (accountsForType != null) { 2356f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana System.arraycopy(accountsForType, 0, newAccountsForType, 0, oldLength); 2357f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 2358f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana newAccountsForType[oldLength] = account; 235904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.accountCache.put(account.type, newAccountsForType); 2360f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 2361f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana 236204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani protected Account[] getAccountsFromCacheLocked(UserAccounts userAccounts, String accountType) { 2363f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (accountType != null) { 236404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final Account[] accounts = userAccounts.accountCache.get(accountType); 2365f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (accounts == null) { 2366f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return EMPTY_ACCOUNT_ARRAY; 236756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } else { 2368f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return Arrays.copyOf(accounts, accounts.length); 2369f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 2370f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } else { 2371f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana int totalLength = 0; 237204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani for (Account[] accounts : userAccounts.accountCache.values()) { 2373f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana totalLength += accounts.length; 2374f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 2375f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (totalLength == 0) { 2376f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return EMPTY_ACCOUNT_ARRAY; 2377f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 2378f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana Account[] accounts = new Account[totalLength]; 2379f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana totalLength = 0; 238004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani for (Account[] accountsOfType : userAccounts.accountCache.values()) { 2381f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana System.arraycopy(accountsOfType, 0, accounts, totalLength, 2382f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana accountsOfType.length); 2383f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana totalLength += accountsOfType.length; 238456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 2385f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return accounts; 238656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 238756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 238856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 238904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani protected void writeUserDataIntoCacheLocked(UserAccounts accounts, final SQLiteDatabase db, 239004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani Account account, String key, String value) { 239104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani HashMap<String, String> userDataForAccount = accounts.userDataCache.get(account); 2392f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (userDataForAccount == null) { 2393f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana userDataForAccount = readUserDataForAccountFromDatabaseLocked(db, account); 239404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.userDataCache.put(account, userDataForAccount); 2395f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 2396f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (value == null) { 2397f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana userDataForAccount.remove(key); 2398f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } else { 2399f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana userDataForAccount.put(key, value); 240056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 240156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 240256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 240304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani protected void writeAuthTokenIntoCacheLocked(UserAccounts accounts, final SQLiteDatabase db, 240404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani Account account, String key, String value) { 240504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani HashMap<String, String> authTokensForAccount = accounts.authTokenCache.get(account); 2406f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (authTokensForAccount == null) { 2407f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana authTokensForAccount = readAuthTokensForAccountFromDatabaseLocked(db, account); 240804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.authTokenCache.put(account, authTokensForAccount); 2409f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 2410f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (value == null) { 2411f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana authTokensForAccount.remove(key); 2412f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } else { 2413f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana authTokensForAccount.put(key, value); 241456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 241556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 241656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 241704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani protected String readAuthTokenInternal(UserAccounts accounts, Account account, 241804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani String authTokenType) { 241904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 242004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani HashMap<String, String> authTokensForAccount = accounts.authTokenCache.get(account); 242156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (authTokensForAccount == null) { 242256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana // need to populate the cache for this account 242304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getReadableDatabase(); 2424f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana authTokensForAccount = readAuthTokensForAccountFromDatabaseLocked(db, account); 242504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.authTokenCache.put(account, authTokensForAccount); 242656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 242756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana return authTokensForAccount.get(authTokenType); 242856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 242956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 243056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 243104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani protected String readUserDataInternal(UserAccounts accounts, Account account, String key) { 243204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 243304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani HashMap<String, String> userDataForAccount = accounts.userDataCache.get(account); 243456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (userDataForAccount == null) { 243556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana // need to populate the cache for this account 243604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getReadableDatabase(); 2437f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana userDataForAccount = readUserDataForAccountFromDatabaseLocked(db, account); 243804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.userDataCache.put(account, userDataForAccount); 243956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 244056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana return userDataForAccount.get(key); 244156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 244256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 244356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 2444f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana protected HashMap<String, String> readUserDataForAccountFromDatabaseLocked( 2445f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana final SQLiteDatabase db, Account account) { 244656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana HashMap<String, String> userDataForAccount = new HashMap<String, String>(); 244756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Cursor cursor = db.query(TABLE_EXTRAS, 244856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana COLUMNS_EXTRAS_KEY_AND_VALUE, 244956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana SELECTION_USERDATA_BY_ACCOUNT, 245056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana new String[]{account.name, account.type}, 245156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana null, null, null); 245256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana try { 245356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana while (cursor.moveToNext()) { 245456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final String tmpkey = cursor.getString(0); 245556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final String value = cursor.getString(1); 245656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana userDataForAccount.put(tmpkey, value); 245756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 245856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } finally { 245956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana cursor.close(); 246056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 246156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana return userDataForAccount; 246256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 246356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 2464f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana protected HashMap<String, String> readAuthTokensForAccountFromDatabaseLocked( 2465f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana final SQLiteDatabase db, Account account) { 246656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana HashMap<String, String> authTokensForAccount = new HashMap<String, String>(); 246756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Cursor cursor = db.query(TABLE_AUTHTOKENS, 246856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana COLUMNS_AUTHTOKENS_TYPE_AND_AUTHTOKEN, 246956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana SELECTION_AUTHTOKENS_BY_ACCOUNT, 247056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana new String[]{account.name, account.type}, 247156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana null, null, null); 247256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana try { 247356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana while (cursor.moveToNext()) { 247456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final String type = cursor.getString(0); 247556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final String authToken = cursor.getString(1); 247656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana authTokensForAccount.put(type, authToken); 247756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 247856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } finally { 247956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana cursor.close(); 248056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 248156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana return authTokensForAccount; 248256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 2483603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana} 2484