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; 216ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkeyimport android.app.ActivityManagerNative; 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; 356ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkeyimport android.content.pm.PackageManager.NameNotFoundException; 36d4a1d2e14297a3387fdb5761090961e714370492Fred Quintanaimport android.content.pm.RegisteredServicesCache; 373ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintanaimport android.content.pm.RegisteredServicesCacheListener; 386eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkeyimport android.content.pm.UserInfo; 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; 53f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackbornimport android.os.UserHandle; 54258848d2ae04f447ff1c18023fa76b139fcc0862Amith Yamasaniimport android.os.UserManager; 55a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.text.TextUtils; 56a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.util.Log; 57d4a1d2e14297a3387fdb5761090961e714370492Fred Quintanaimport android.util.Pair; 586eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkeyimport android.util.Slog; 5904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasaniimport android.util.SparseArray; 60603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 61b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolacheimport com.android.internal.R; 6204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasaniimport com.android.internal.util.IndentingPrintWriter; 636ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkeyimport com.google.android.collect.Lists; 646ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkeyimport com.google.android.collect.Sets; 65b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache 66a8529f68671a8a118751cb6ad577f44eaf076b96Oscar Montemayorimport java.io.File; 67a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport java.io.FileDescriptor; 68a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport java.io.PrintWriter; 69a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport java.util.ArrayList; 7056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintanaimport java.util.Arrays; 71a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport java.util.Collection; 72d4a1d2e14297a3387fdb5761090961e714370492Fred Quintanaimport java.util.HashMap; 736ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkeyimport java.util.HashSet; 7456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintanaimport java.util.LinkedHashMap; 756eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkeyimport java.util.List; 762f36229db823d152f3efd879e751e81a601a75b0Andy McFaddenimport java.util.Map; 77d4a1d2e14297a3387fdb5761090961e714370492Fred Quintanaimport java.util.concurrent.atomic.AtomicInteger; 78d4a1d2e14297a3387fdb5761090961e714370492Fred Quintanaimport java.util.concurrent.atomic.AtomicReference; 79603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 80603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana/** 81603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * A system service that provides account, password, and authtoken management for all 82603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * accounts on the device. Some of these calls are implemented with the help of the corresponding 83603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * {@link IAccountAuthenticator} services. This service is not accessed by users directly, 84603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * instead one uses an instance of {@link AccountManager}, which can be accessed as follows: 8546703b099516c383a6882815bcf9cd4df0ec538dBrian Carlstrom * AccountManager accountManager = AccountManager.get(context); 863326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana * @hide 87603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana */ 883ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintanapublic class AccountManagerService 893ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintana extends IAccountManager.Stub 905ebbb4a6b3e16f711735ae0615b9a9ea64faad38Fred Quintana implements RegisteredServicesCacheListener<AuthenticatorDescription> { 91603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String TAG = "AccountManagerService"; 92603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 93603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final int TIMEOUT_DELAY_MS = 1000 * 60; 94603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String DATABASE_NAME = "accounts.db"; 953348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache private static final int DATABASE_VERSION = 4; 96603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 97603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private final Context mContext; 98603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 9956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana private final PackageManager mPackageManager; 100258848d2ae04f447ff1c18023fa76b139fcc0862Amith Yamasani private UserManager mUserManager; 10156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 102603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private HandlerThread mMessageThread; 103603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private final MessageHandler mMessageHandler; 104603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 105603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana // Messages that can be sent on mHandler 106603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final int MESSAGE_TIMED_OUT = 3; 107603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 10856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana private final IAccountAuthenticatorCache mAuthenticatorCache; 109603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 110603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String TABLE_ACCOUNTS = "accounts"; 111603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String ACCOUNTS_ID = "_id"; 112603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String ACCOUNTS_NAME = "name"; 113603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String ACCOUNTS_TYPE = "type"; 1141cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks private static final String ACCOUNTS_TYPE_COUNT = "count(type)"; 115603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String ACCOUNTS_PASSWORD = "password"; 116603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 117603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String TABLE_AUTHTOKENS = "authtokens"; 118603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String AUTHTOKENS_ID = "_id"; 119603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String AUTHTOKENS_ACCOUNTS_ID = "accounts_id"; 120603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String AUTHTOKENS_TYPE = "type"; 121603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String AUTHTOKENS_AUTHTOKEN = "authtoken"; 122603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 123d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private static final String TABLE_GRANTS = "grants"; 124d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private static final String GRANTS_ACCOUNTS_ID = "accounts_id"; 125d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private static final String GRANTS_AUTH_TOKEN_TYPE = "auth_token_type"; 126d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private static final String GRANTS_GRANTEE_UID = "uid"; 127d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 128603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String TABLE_EXTRAS = "extras"; 129603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String EXTRAS_ID = "_id"; 130603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String EXTRAS_ACCOUNTS_ID = "accounts_id"; 131603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String EXTRAS_KEY = "key"; 132603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String EXTRAS_VALUE = "value"; 133603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 134603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String TABLE_META = "meta"; 135603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String META_KEY = "key"; 136603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String META_VALUE = "value"; 137603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1381cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks private static final String[] ACCOUNT_TYPE_COUNT_PROJECTION = 1391cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks new String[] { ACCOUNTS_TYPE, ACCOUNTS_TYPE_COUNT}; 1407be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana private static final Intent ACCOUNTS_CHANGED_INTENT; 141a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 142d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private static final String COUNT_OF_MATCHING_GRANTS = "" 143d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + "SELECT COUNT(*) FROM " + TABLE_GRANTS + ", " + TABLE_ACCOUNTS 144d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + " WHERE " + GRANTS_ACCOUNTS_ID + "=" + ACCOUNTS_ID 145d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + " AND " + GRANTS_GRANTEE_UID + "=?" 146d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + " AND " + GRANTS_AUTH_TOKEN_TYPE + "=?" 147d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + " AND " + ACCOUNTS_NAME + "=?" 148d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + " AND " + ACCOUNTS_TYPE + "=?"; 149d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 15056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana private static final String SELECTION_AUTHTOKENS_BY_ACCOUNT = 15156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana AUTHTOKENS_ACCOUNTS_ID + "=(select _id FROM accounts WHERE name=? AND type=?)"; 15256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana private static final String[] COLUMNS_AUTHTOKENS_TYPE_AND_AUTHTOKEN = {AUTHTOKENS_TYPE, 15356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana AUTHTOKENS_AUTHTOKEN}; 15456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 15556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana private static final String SELECTION_USERDATA_BY_ACCOUNT = 15656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana EXTRAS_ACCOUNTS_ID + "=(select _id FROM accounts WHERE name=? AND type=?)"; 15756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana private static final String[] COLUMNS_EXTRAS_KEY_AND_VALUE = {EXTRAS_KEY, EXTRAS_VALUE}; 15856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 159a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana private final LinkedHashMap<String, Session> mSessions = new LinkedHashMap<String, Session>(); 160d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private final AtomicInteger mNotificationIds = new AtomicInteger(1); 161d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 16204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani static class UserAccounts { 16304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private final int userId; 16404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private final DatabaseHelper openHelper; 16504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private final HashMap<Pair<Pair<Account, String>, Integer>, Integer> 16604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani credentialsPermissionNotificationIds = 16704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani new HashMap<Pair<Pair<Account, String>, Integer>, Integer>(); 16804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private final HashMap<Account, Integer> signinRequiredNotificationIds = 16904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani new HashMap<Account, Integer>(); 17004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private final Object cacheLock = new Object(); 17104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani /** protected by the {@link #cacheLock} */ 172b483a99c6bdfee72fbb8fbcf893e63ef3f54658bAmith Yamasani private final HashMap<String, Account[]> accountCache = 173b483a99c6bdfee72fbb8fbcf893e63ef3f54658bAmith Yamasani new LinkedHashMap<String, Account[]>(); 17404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani /** protected by the {@link #cacheLock} */ 17504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private HashMap<Account, HashMap<String, String>> userDataCache = 17604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani new HashMap<Account, HashMap<String, String>>(); 17704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani /** protected by the {@link #cacheLock} */ 17804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private HashMap<Account, HashMap<String, String>> authTokenCache = 17904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani new HashMap<Account, HashMap<String, String>>(); 18004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani 18104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts(Context context, int userId) { 18204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani this.userId = userId; 18304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (cacheLock) { 18404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani openHelper = new DatabaseHelper(context, userId); 18504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 18604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 18704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 18804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani 18904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private final SparseArray<UserAccounts> mUsers = new SparseArray<UserAccounts>(); 19004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani 191d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private static AtomicReference<AccountManagerService> sThis = 192d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana new AtomicReference<AccountManagerService>(); 19331957f1badbb900bbfe211317e1ea992d650a72dFred Quintana private static final Account[] EMPTY_ACCOUNT_ARRAY = new Account[]{}; 1947be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana 1957be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana static { 196f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana ACCOUNTS_CHANGED_INTENT = new Intent(AccountManager.LOGIN_ACCOUNTS_CHANGED_ACTION); 1977be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana ACCOUNTS_CHANGED_INTENT.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 1987be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana } 1997be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana 20056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 201d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana /** 202d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * This should only be called by system code. One should only call this after the service 203d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * has started. 204d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * @return a reference to the AccountManagerService instance 205d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * @hide 206d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana */ 207d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana public static AccountManagerService getSingleton() { 208d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana return sThis.get(); 209d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 210603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 21156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana public AccountManagerService(Context context) { 21256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana this(context, context.getPackageManager(), new AccountAuthenticatorCache(context)); 213603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 214603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 21556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana public AccountManagerService(Context context, PackageManager packageManager, 21656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana IAccountAuthenticatorCache authenticatorCache) { 217603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mContext = context; 21856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana mPackageManager = packageManager; 219603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 220603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mMessageThread = new HandlerThread("AccountManagerService"); 221603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mMessageThread.start(); 222603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mMessageHandler = new MessageHandler(mMessageThread.getLooper()); 223603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 22456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana mAuthenticatorCache = authenticatorCache; 2255ebbb4a6b3e16f711735ae0615b9a9ea64faad38Fred Quintana mAuthenticatorCache.setListener(this, null /* Handler */); 226603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 227d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana sThis.set(this); 228afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana 229c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana IntentFilter intentFilter = new IntentFilter(); 230c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED); 231c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana intentFilter.addDataScheme("package"); 232c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana mContext.registerReceiver(new BroadcastReceiver() { 233c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana @Override 234c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana public void onReceive(Context context1, Intent intent) { 23504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani purgeOldGrantsAll(); 236c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana } 237c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana }, intentFilter); 238c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana 239135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani IntentFilter userFilter = new IntentFilter(); 240135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani userFilter.addAction(Intent.ACTION_USER_REMOVED); 241135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani mContext.registerReceiver(new BroadcastReceiver() { 242135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani @Override 243135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani public void onReceive(Context context, Intent intent) { 244135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani onUserRemoved(intent); 245135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani } 246135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani }, userFilter); 247afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana } 248afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana 24926ff6626fc4ee0ae46f01ad309b366921da589feKenny Root public void systemReady() { 25026ff6626fc4ee0ae46f01ad309b366921da589feKenny Root } 25126ff6626fc4ee0ae46f01ad309b366921da589feKenny Root 252258848d2ae04f447ff1c18023fa76b139fcc0862Amith Yamasani private UserManager getUserManager() { 253258848d2ae04f447ff1c18023fa76b139fcc0862Amith Yamasani if (mUserManager == null) { 254258848d2ae04f447ff1c18023fa76b139fcc0862Amith Yamasani mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); 255258848d2ae04f447ff1c18023fa76b139fcc0862Amith Yamasani } 256258848d2ae04f447ff1c18023fa76b139fcc0862Amith Yamasani return mUserManager; 257258848d2ae04f447ff1c18023fa76b139fcc0862Amith Yamasani } 258258848d2ae04f447ff1c18023fa76b139fcc0862Amith Yamasani 25904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private UserAccounts initUser(int userId) { 26004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (mUsers) { 26104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = mUsers.get(userId); 26204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani if (accounts == null) { 26304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts = new UserAccounts(mContext, userId); 26404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani mUsers.append(userId, accounts); 26504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani purgeOldGrants(accounts); 2666eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey validateAccountsInternal(accounts, true /* invalidateAuthenticatorCache */); 26704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 26804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani return accounts; 26904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 27004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 27104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani 27204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private void purgeOldGrantsAll() { 27304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (mUsers) { 27404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani for (int i = 0; i < mUsers.size(); i++) { 27504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani purgeOldGrants(mUsers.valueAt(i)); 27604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 27704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 27804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 27904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani 28004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private void purgeOldGrants(UserAccounts accounts) { 28104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 28204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getWritableDatabase(); 283c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana final Cursor cursor = db.query(TABLE_GRANTS, 284c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana new String[]{GRANTS_GRANTEE_UID}, 285c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana null, null, GRANTS_GRANTEE_UID, null, null); 286c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana try { 287c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana while (cursor.moveToNext()) { 288c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana final int uid = cursor.getInt(0); 289c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana final boolean packageExists = mPackageManager.getPackagesForUid(uid) != null; 290c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana if (packageExists) { 291c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana continue; 292c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana } 293c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana Log.d(TAG, "deleting grants for UID " + uid 294c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana + " because its package is no longer installed"); 295c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana db.delete(TABLE_GRANTS, GRANTS_GRANTEE_UID + "=?", 296c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana new String[]{Integer.toString(uid)}); 297c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana } 298c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana } finally { 299c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana cursor.close(); 300c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana } 301c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana } 302c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana } 303c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana 3046eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey /** 3056eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey * Validate internal set of accounts against installed authenticators for 3066eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey * given user. Clears cached authenticators before validating. 3076eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey */ 3086eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey public void validateAccounts(int userId) { 3096eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey final UserAccounts accounts = getUserAccounts(userId); 3106eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey 3116eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey // Invalidate user-specific cache to make sure we catch any 3126eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey // removed authenticators. 3136eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey validateAccountsInternal(accounts, true /* invalidateAuthenticatorCache */); 3146eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey } 3156eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey 3166eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey /** 3176eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey * Validate internal set of accounts against installed authenticators for 3186eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey * given user. Clear cached authenticators before validating when requested. 3196eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey */ 3206eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey private void validateAccountsInternal( 3216eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey UserAccounts accounts, boolean invalidateAuthenticatorCache) { 3226eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey if (invalidateAuthenticatorCache) { 3236eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey mAuthenticatorCache.invalidateCache(accounts.userId); 3246eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey } 3256eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey 3266ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey final HashSet<AuthenticatorDescription> knownAuth = Sets.newHashSet(); 3276ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey for (RegisteredServicesCache.ServiceInfo<AuthenticatorDescription> service : 3286ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey mAuthenticatorCache.getAllServices(accounts.userId)) { 3296ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey knownAuth.add(service.type); 3306ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey } 3316ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey 33204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 33304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getWritableDatabase(); 334f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana boolean accountDeleted = false; 335f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana Cursor cursor = db.query(TABLE_ACCOUNTS, 336f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana new String[]{ACCOUNTS_ID, ACCOUNTS_TYPE, ACCOUNTS_NAME}, 337f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana null, null, null, null, null); 338f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana try { 33904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.accountCache.clear(); 34056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final HashMap<String, ArrayList<String>> accountNamesByType = 341b483a99c6bdfee72fbb8fbcf893e63ef3f54658bAmith Yamasani new LinkedHashMap<String, ArrayList<String>>(); 34256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana while (cursor.moveToNext()) { 34356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final long accountId = cursor.getLong(0); 34456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final String accountType = cursor.getString(1); 34556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final String accountName = cursor.getString(2); 3466ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey 3476ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey if (!knownAuth.contains(AuthenticatorDescription.newKey(accountType))) { 3486eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey Slog.w(TAG, "deleting account " + accountName + " because type " 34956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + accountType + " no longer has a registered authenticator"); 35056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana db.delete(TABLE_ACCOUNTS, ACCOUNTS_ID + "=" + accountId, null); 35156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana accountDeleted = true; 35256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final Account account = new Account(accountName, accountType); 35304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.userDataCache.remove(account); 35404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.authTokenCache.remove(account); 35556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } else { 35656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana ArrayList<String> accountNames = accountNamesByType.get(accountType); 35756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (accountNames == null) { 35856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana accountNames = new ArrayList<String>(); 35956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana accountNamesByType.put(accountType, accountNames); 36056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 36156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana accountNames.add(accountName); 36256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 36356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 3642f36229db823d152f3efd879e751e81a601a75b0Andy McFadden for (Map.Entry<String, ArrayList<String>> cur 365f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana : accountNamesByType.entrySet()) { 36656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final String accountType = cur.getKey(); 36756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final ArrayList<String> accountNames = cur.getValue(); 36856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final Account[] accountsForType = new Account[accountNames.size()]; 36956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana int i = 0; 37056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana for (String accountName : accountNames) { 37156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana accountsForType[i] = new Account(accountName, accountType); 37256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana ++i; 37356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 37404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.accountCache.put(accountType, accountsForType); 375afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana } 376f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } finally { 377f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana cursor.close(); 378f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (accountDeleted) { 37904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani sendAccountsChangedBroadcast(accounts.userId); 380f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 381afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana } 382afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana } 3833ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintana } 3843ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintana 38504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private UserAccounts getUserAccountsForCaller() { 386f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackborn return getUserAccounts(UserHandle.getCallingUserId()); 38704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 38804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani 38904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani protected UserAccounts getUserAccounts(int userId) { 39004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (mUsers) { 39104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = mUsers.get(userId); 39204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani if (accounts == null) { 39304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts = initUser(userId); 39404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani mUsers.append(userId, accounts); 39504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 39604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani return accounts; 39704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 39804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 39904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani 400135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani private void onUserRemoved(Intent intent) { 4012a00329c6d55c6cd9166e01963d7410e95d80d21Amith Yamasani int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); 402135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani if (userId < 1) return; 403135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani 404135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani UserAccounts accounts; 405135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani synchronized (mUsers) { 406135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani accounts = mUsers.get(userId); 407135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani mUsers.remove(userId); 408135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani } 409135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani if (accounts == null) { 410135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani File dbFile = new File(getDatabaseName(userId)); 411135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani dbFile.delete(); 412135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani return; 413135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani } 414135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani 415135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani synchronized (accounts.cacheLock) { 416135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani accounts.openHelper.close(); 417135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani File dbFile = new File(getDatabaseName(userId)); 418135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani dbFile.delete(); 419135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani } 420135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani } 421135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani 4226ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey @Override 4236ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey public void onServiceChanged(AuthenticatorDescription desc, int userId, boolean removed) { 4246eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey Slog.d(TAG, "onServiceChanged() for userId " + userId); 4256eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey validateAccountsInternal(getUserAccounts(userId), false /* invalidateAuthenticatorCache */); 426603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 427603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 428a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public String getPassword(Account account) { 42956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 43056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "getPassword: " + account 43156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 43256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 43356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 434382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 435d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkAuthenticateAccountsPermission(account); 436d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 43704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 43826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 439603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana try { 44004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani return readPasswordInternal(accounts, account); 441603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } finally { 44226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 443603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 444603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 445603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 44604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private String readPasswordInternal(UserAccounts accounts, Account account) { 44731957f1badbb900bbfe211317e1ea992d650a72dFred Quintana if (account == null) { 44831957f1badbb900bbfe211317e1ea992d650a72dFred Quintana return null; 44931957f1badbb900bbfe211317e1ea992d650a72dFred Quintana } 45031957f1badbb900bbfe211317e1ea992d650a72dFred Quintana 45104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 45204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getReadableDatabase(); 453f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana Cursor cursor = db.query(TABLE_ACCOUNTS, new String[]{ACCOUNTS_PASSWORD}, 454f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?", 455f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana new String[]{account.name, account.type}, null, null, null); 456f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana try { 457f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (cursor.moveToNext()) { 458f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return cursor.getString(0); 459f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 460f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return null; 461f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } finally { 462f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana cursor.close(); 463ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 464ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 465ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 466ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 467a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public String getUserData(Account account, String key) { 46856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 46956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "getUserData: " + account 47056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", key " + key 47156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 47256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 47356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 474382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 475382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (key == null) throw new IllegalArgumentException("key is null"); 476d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkAuthenticateAccountsPermission(account); 47704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 47826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 479603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana try { 48004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani return readUserDataInternal(accounts, account, key); 481ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } finally { 482ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana restoreCallingIdentity(identityToken); 483ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 484ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 485ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 4869788976b1465ce982b5ae7c741345edd0ecd9322Fred Quintana public AuthenticatorDescription[] getAuthenticatorTypes() { 48756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 48856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "getAuthenticatorTypes: " 48956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + "caller's uid " + Binder.getCallingUid() 49056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 49156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 4926ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey final int userId = UserHandle.getCallingUserId(); 4936ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey final long identityToken = clearCallingIdentity(); 49426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 4959788976b1465ce982b5ae7c741345edd0ecd9322Fred Quintana Collection<AccountAuthenticatorCache.ServiceInfo<AuthenticatorDescription>> 4966ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey authenticatorCollection = mAuthenticatorCache.getAllServices(userId); 4979788976b1465ce982b5ae7c741345edd0ecd9322Fred Quintana AuthenticatorDescription[] types = 4989788976b1465ce982b5ae7c741345edd0ecd9322Fred Quintana new AuthenticatorDescription[authenticatorCollection.size()]; 49926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana int i = 0; 5009788976b1465ce982b5ae7c741345edd0ecd9322Fred Quintana for (AccountAuthenticatorCache.ServiceInfo<AuthenticatorDescription> authenticator 501718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana : authenticatorCollection) { 502718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana types[i] = authenticator.type; 50326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana i++; 50426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 50526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana return types; 50626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 50726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 508a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 509a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 510a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 511a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public boolean addAccount(Account account, String password, Bundle extras) { 51256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 51356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "addAccount: " + account 51456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 51556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 51656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 517382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 518d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkAuthenticateAccountsPermission(account); 519d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 52004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 521603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana // fails if the account already exists 52226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 523603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana try { 52404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani return addAccountInternal(accounts, account, password, extras); 525ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } finally { 526ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana restoreCallingIdentity(identityToken); 527ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 528ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 529ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 53004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private boolean addAccountInternal(UserAccounts accounts, Account account, String password, 53104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani Bundle extras) { 532743dfad2a51e016ddb741c104317637089187753Fred Quintana if (account == null) { 533743dfad2a51e016ddb741c104317637089187753Fred Quintana return false; 534743dfad2a51e016ddb741c104317637089187753Fred Quintana } 53504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 53604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getWritableDatabase(); 537f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.beginTransaction(); 538f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana try { 539f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana long numMatches = DatabaseUtils.longForQuery(db, 540f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana "select count(*) from " + TABLE_ACCOUNTS 541f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana + " WHERE " + ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?", 542f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana new String[]{account.name, account.type}); 543f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (numMatches > 0) { 544f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana Log.w(TAG, "insertAccountIntoDatabase: " + account 545f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana + ", skipping since the account already exists"); 546f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return false; 547f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 548f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana ContentValues values = new ContentValues(); 549f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana values.put(ACCOUNTS_NAME, account.name); 550f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana values.put(ACCOUNTS_TYPE, account.type); 551f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana values.put(ACCOUNTS_PASSWORD, password); 552f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana long accountId = db.insert(TABLE_ACCOUNTS, ACCOUNTS_NAME, values); 553f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (accountId < 0) { 554f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana Log.w(TAG, "insertAccountIntoDatabase: " + account 555f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana + ", skipping the DB insert failed"); 556f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return false; 557f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 558f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (extras != null) { 559f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana for (String key : extras.keySet()) { 560f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana final String value = extras.getString(key); 561f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (insertExtraLocked(db, accountId, key, value) < 0) { 562f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana Log.w(TAG, "insertAccountIntoDatabase: " + account 563f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana + ", skipping since insertExtra failed for key " + key); 564f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return false; 565f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 566603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 567603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 568f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.setTransactionSuccessful(); 56904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani insertAccountIntoCacheLocked(accounts, account); 570f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } finally { 571f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.endTransaction(); 572603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 57304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani sendAccountsChangedBroadcast(accounts.userId); 574f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return true; 575603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 576603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 577603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 578f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana private long insertExtraLocked(SQLiteDatabase db, long accountId, String key, String value) { 579603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana ContentValues values = new ContentValues(); 580603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana values.put(EXTRAS_KEY, key); 581603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana values.put(EXTRAS_ACCOUNTS_ID, accountId); 582603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana values.put(EXTRAS_VALUE, value); 583603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana return db.insert(TABLE_EXTRAS, EXTRAS_KEY, values); 584603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 585603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 5863084a6f80180506ce26fe4773d9a19f004b7f625Fred Quintana public void hasFeatures(IAccountManagerResponse response, 587bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana Account account, String[] features) { 58856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 58956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "hasFeatures: " + account 59056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", response " + response 59156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", features " + stringArrayToString(features) 59256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 59356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 59456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 595382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (response == null) throw new IllegalArgumentException("response is null"); 596382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 597382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (features == null) throw new IllegalArgumentException("features is null"); 598bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana checkReadAccountsPermission(); 59904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 600bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana long identityToken = clearCallingIdentity(); 601bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana try { 60204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani new TestFeaturesSession(accounts, response, account, features).bind(); 603bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } finally { 604bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana restoreCallingIdentity(identityToken); 605bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 606bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 607bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana 608bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana private class TestFeaturesSession extends Session { 609bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana private final String[] mFeatures; 610bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana private final Account mAccount; 611bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana 61204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani public TestFeaturesSession(UserAccounts accounts, IAccountManagerResponse response, 613bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana Account account, String[] features) { 61404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani super(accounts, response, account.type, false /* expectActivityLaunch */, 6158570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana true /* stripAuthTokenFromResult */); 616bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana mFeatures = features; 617bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana mAccount = account; 618bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 619bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana 620bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana public void run() throws RemoteException { 621bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana try { 622bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana mAuthenticator.hasFeatures(this, mAccount, mFeatures); 623bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } catch (RemoteException e) { 624bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana onError(AccountManager.ERROR_CODE_REMOTE_EXCEPTION, "remote exception"); 625bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 626bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 627bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana 628bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana public void onResult(Bundle result) { 629bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana IAccountManagerResponse response = getResponseAndClose(); 630bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana if (response != null) { 631bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana try { 632bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana if (result == null) { 633166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana response.onError(AccountManager.ERROR_CODE_INVALID_RESPONSE, "null bundle"); 634bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana return; 635bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 63656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 63756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, getClass().getSimpleName() + " calling onResult() on response " 63856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + response); 63956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 640bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana final Bundle newResult = new Bundle(); 641bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana newResult.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, 642bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT, false)); 643bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana response.onResult(newResult); 644bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } catch (RemoteException e) { 645bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana // if the caller is dead then there is no one to care about remote exceptions 646bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 647bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana Log.v(TAG, "failure while notifying response", e); 648bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 649bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 650bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 651bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 652bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana 653bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana protected String toDebugString(long now) { 6543084a6f80180506ce26fe4773d9a19f004b7f625Fred Quintana return super.toDebugString(now) + ", hasFeatures" 655bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana + ", " + mAccount 656bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana + ", " + (mFeatures != null ? TextUtils.join(",", mFeatures) : null); 657bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 658bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 659307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana 660ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana public void removeAccount(IAccountManagerResponse response, Account account) { 66156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 66256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "removeAccount: " + account 66356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", response " + response 66456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 66556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 66656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 667382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (response == null) throw new IllegalArgumentException("response is null"); 668382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 669d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkManageAccountsPermission(); 67050cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn UserHandle user = Binder.getCallingUserHandle(); 67104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 67226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 673ec0c4f4183630a64c2b2cc8f961dc7e11cc628caCostin Manolache 67450cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn cancelNotification(getSigninRequiredNotificationId(accounts, account), user); 67504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized(accounts.credentialsPermissionNotificationIds) { 676ec0c4f4183630a64c2b2cc8f961dc7e11cc628caCostin Manolache for (Pair<Pair<Account, String>, Integer> pair: 67704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.credentialsPermissionNotificationIds.keySet()) { 678ec0c4f4183630a64c2b2cc8f961dc7e11cc628caCostin Manolache if (account.equals(pair.first.first)) { 67904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani int id = accounts.credentialsPermissionNotificationIds.get(pair); 68050cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn cancelNotification(id, user); 681ec0c4f4183630a64c2b2cc8f961dc7e11cc628caCostin Manolache } 682ec0c4f4183630a64c2b2cc8f961dc7e11cc628caCostin Manolache } 683ec0c4f4183630a64c2b2cc8f961dc7e11cc628caCostin Manolache } 684ec0c4f4183630a64c2b2cc8f961dc7e11cc628caCostin Manolache 68526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 68604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani new RemoveAccountSession(accounts, response, account).bind(); 68726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 68826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 689a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 690603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 691603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 692ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana private class RemoveAccountSession extends Session { 693ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana final Account mAccount; 69404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani public RemoveAccountSession(UserAccounts accounts, IAccountManagerResponse response, 69504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani Account account) { 69604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani super(accounts, response, account.type, false /* expectActivityLaunch */, 6978570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana true /* stripAuthTokenFromResult */); 698ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana mAccount = account; 699ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 700ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 701ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana protected String toDebugString(long now) { 702ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana return super.toDebugString(now) + ", removeAccount" 703ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana + ", account " + mAccount; 704ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 705ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 706ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana public void run() throws RemoteException { 707ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana mAuthenticator.getAccountRemovalAllowed(this, mAccount); 708ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 709ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 710ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana public void onResult(Bundle result) { 711f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana if (result != null && result.containsKey(AccountManager.KEY_BOOLEAN_RESULT) 712f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana && !result.containsKey(AccountManager.KEY_INTENT)) { 713f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana final boolean removalAllowed = result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT); 714ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana if (removalAllowed) { 71504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani removeAccountInternal(mAccounts, mAccount); 716ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 717ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana IAccountManagerResponse response = getResponseAndClose(); 718ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana if (response != null) { 71956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 72056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, getClass().getSimpleName() + " calling onResult() on response " 72156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + response); 72256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 723ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana Bundle result2 = new Bundle(); 724f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana result2.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, removalAllowed); 725ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana try { 726ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana response.onResult(result2); 727ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } catch (RemoteException e) { 728ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana // ignore 729ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 730ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 731ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 732ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana super.onResult(result); 733ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 734ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 735ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 73604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani /* For testing */ 737f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana protected void removeAccountInternal(Account account) { 73804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani removeAccountInternal(getUserAccountsForCaller(), account); 73904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 74004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani 74104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private void removeAccountInternal(UserAccounts accounts, Account account) { 74204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 74304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getWritableDatabase(); 744f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.delete(TABLE_ACCOUNTS, ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?", 745f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana new String[]{account.name, account.type}); 74604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani removeAccountFromCacheLocked(accounts, account); 74704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani sendAccountsChangedBroadcast(accounts.userId); 748f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 749ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 750ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 751a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void invalidateAuthToken(String accountType, String authToken) { 75256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 75356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "invalidateAuthToken: accountType " + accountType 75456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 75556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 75656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 757382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (accountType == null) throw new IllegalArgumentException("accountType is null"); 758382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (authToken == null) throw new IllegalArgumentException("authToken is null"); 759b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana checkManageAccountsOrUseCredentialsPermissions(); 76004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 76126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 762603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana try { 76304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 76404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getWritableDatabase(); 765f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.beginTransaction(); 766f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana try { 76704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani invalidateAuthTokenLocked(accounts, db, accountType, authToken); 768f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.setTransactionSuccessful(); 769f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } finally { 770f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.endTransaction(); 771f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 77226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 773603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } finally { 77426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 775603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 776603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 777603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 77804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private void invalidateAuthTokenLocked(UserAccounts accounts, SQLiteDatabase db, 77904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani String accountType, String authToken) { 780ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana if (authToken == null || accountType == null) { 781ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana return; 782ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 7833326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana Cursor cursor = db.rawQuery( 7843326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana "SELECT " + TABLE_AUTHTOKENS + "." + AUTHTOKENS_ID 7853326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + ", " + TABLE_ACCOUNTS + "." + ACCOUNTS_NAME 7863326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + ", " + TABLE_AUTHTOKENS + "." + AUTHTOKENS_TYPE 7873326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + " FROM " + TABLE_ACCOUNTS 7883326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + " JOIN " + TABLE_AUTHTOKENS 7893326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + " ON " + TABLE_ACCOUNTS + "." + ACCOUNTS_ID 7903326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + " = " + AUTHTOKENS_ACCOUNTS_ID 7913326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + " WHERE " + AUTHTOKENS_AUTHTOKEN + " = ? AND " 7923326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + TABLE_ACCOUNTS + "." + ACCOUNTS_TYPE + " = ?", 7933326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana new String[]{authToken, accountType}); 7943326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana try { 7953326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana while (cursor.moveToNext()) { 7963326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana long authTokenId = cursor.getLong(0); 7973326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana String accountName = cursor.getString(1); 7983326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana String authTokenType = cursor.getString(2); 7993326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana db.delete(TABLE_AUTHTOKENS, AUTHTOKENS_ID + "=" + authTokenId, null); 80004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani writeAuthTokenIntoCacheLocked(accounts, db, new Account(accountName, accountType), 801f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana authTokenType, null); 802603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 8033326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } finally { 8043326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana cursor.close(); 805603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 806603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 807603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 80804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private boolean saveAuthTokenToDatabase(UserAccounts accounts, Account account, String type, 80904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani String authToken) { 81031957f1badbb900bbfe211317e1ea992d650a72dFred Quintana if (account == null || type == null) { 81131957f1badbb900bbfe211317e1ea992d650a72dFred Quintana return false; 81231957f1badbb900bbfe211317e1ea992d650a72dFred Quintana } 81350cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn cancelNotification(getSigninRequiredNotificationId(accounts, account), 81450cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn new UserHandle(accounts.userId)); 81504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 81604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getWritableDatabase(); 817f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.beginTransaction(); 818f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana try { 819f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana long accountId = getAccountIdLocked(db, account); 820f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (accountId < 0) { 821f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return false; 822f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 823f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.delete(TABLE_AUTHTOKENS, 824f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana AUTHTOKENS_ACCOUNTS_ID + "=" + accountId + " AND " + AUTHTOKENS_TYPE + "=?", 825f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana new String[]{type}); 826f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana ContentValues values = new ContentValues(); 827f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana values.put(AUTHTOKENS_ACCOUNTS_ID, accountId); 828f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana values.put(AUTHTOKENS_TYPE, type); 829f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana values.put(AUTHTOKENS_AUTHTOKEN, authToken); 830f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (db.insert(TABLE_AUTHTOKENS, AUTHTOKENS_AUTHTOKEN, values) >= 0) { 831f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.setTransactionSuccessful(); 83204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani writeAuthTokenIntoCacheLocked(accounts, db, account, type, authToken); 833f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return true; 834f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 8353326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana return false; 836f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } finally { 837f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.endTransaction(); 8383326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 839603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 840603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 841603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 842a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public String peekAuthToken(Account account, String authTokenType) { 84356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 84456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "peekAuthToken: " + account 84556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", authTokenType " + authTokenType 84656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 84756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 84856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 849382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 850382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null"); 851d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkAuthenticateAccountsPermission(account); 85204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 85326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 85426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 85504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani return readAuthTokenInternal(accounts, account, authTokenType); 85626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 85726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 858603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 859603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 860603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 861a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void setAuthToken(Account account, String authTokenType, String authToken) { 86256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 86356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "setAuthToken: " + account 86456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", authTokenType " + authTokenType 86556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 86656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 86756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 868382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 869382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null"); 870d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkAuthenticateAccountsPermission(account); 87104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 87226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 87326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 87404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani saveAuthTokenToDatabase(accounts, account, authTokenType, authToken); 87526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 87626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 87726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 878603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 879603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 880a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void setPassword(Account account, String password) { 88156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 88256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "setAuthToken: " + account 88356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 88456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 88556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 886382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 887d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkAuthenticateAccountsPermission(account); 88804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 88926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 89026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 89104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani setPasswordInternal(accounts, account, password); 89226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 89326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 89426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 895603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 896603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 89704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private void setPasswordInternal(UserAccounts accounts, Account account, String password) { 89831957f1badbb900bbfe211317e1ea992d650a72dFred Quintana if (account == null) { 89931957f1badbb900bbfe211317e1ea992d650a72dFred Quintana return; 90031957f1badbb900bbfe211317e1ea992d650a72dFred Quintana } 90104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 90204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getWritableDatabase(); 903f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.beginTransaction(); 904f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana try { 905f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana final ContentValues values = new ContentValues(); 906f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana values.put(ACCOUNTS_PASSWORD, password); 907f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana final long accountId = getAccountIdLocked(db, account); 908f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (accountId >= 0) { 909f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana final String[] argsAccountId = {String.valueOf(accountId)}; 910f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.update(TABLE_ACCOUNTS, values, ACCOUNTS_ID + "=?", argsAccountId); 911f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.delete(TABLE_AUTHTOKENS, AUTHTOKENS_ACCOUNTS_ID + "=?", argsAccountId); 91204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.authTokenCache.remove(account); 913f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.setTransactionSuccessful(); 914f5ffe89e736caee1419f0acb469565d5100b8fb8Costin Manolache } 915f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } finally { 916f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.endTransaction(); 917d4a9d6c42bb412e27a8383aaacd051419d98a662Fred Quintana } 91804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani sendAccountsChangedBroadcast(accounts.userId); 919d4a9d6c42bb412e27a8383aaacd051419d98a662Fred Quintana } 9203ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintana } 9213ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintana 92204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private void sendAccountsChangedBroadcast(int userId) { 92356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.i(TAG, "the accounts changed, sending broadcast of " 92456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ACCOUNTS_CHANGED_INTENT.getAction()); 92579af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn mContext.sendBroadcastAsUser(ACCOUNTS_CHANGED_INTENT, new UserHandle(userId)); 9263326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 9273326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 928a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void clearPassword(Account account) { 92956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 93056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "clearPassword: " + account 93156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 93256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 93356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 934382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 935d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkManageAccountsPermission(); 93604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 93726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 93826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 93904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani setPasswordInternal(accounts, account, null); 94026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 94126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 94226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 943603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 944603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 945a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void setUserData(Account account, String key, String value) { 94656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 94756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "setUserData: " + account 94856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", key " + key 94956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 95056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 95156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 952382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (key == null) throw new IllegalArgumentException("key is null"); 953382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 954d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkAuthenticateAccountsPermission(account); 95504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 95626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 957603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana try { 95804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani setUserdataInternal(accounts, account, key, value); 959ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } finally { 960ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana restoreCallingIdentity(identityToken); 961ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 962ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 963ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 96404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private void setUserdataInternal(UserAccounts accounts, Account account, String key, 96504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani String value) { 96631957f1badbb900bbfe211317e1ea992d650a72dFred Quintana if (account == null || key == null) { 96731957f1badbb900bbfe211317e1ea992d650a72dFred Quintana return; 96831957f1badbb900bbfe211317e1ea992d650a72dFred Quintana } 96904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 97004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getWritableDatabase(); 971f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.beginTransaction(); 972f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana try { 973f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana long accountId = getAccountIdLocked(db, account); 974f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (accountId < 0) { 975ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana return; 97626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 977f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana long extrasId = getExtrasIdLocked(db, accountId, key); 978f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (extrasId < 0 ) { 979f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana extrasId = insertExtraLocked(db, accountId, key, value); 980f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (extrasId < 0) { 981f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return; 982f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 983f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } else { 984f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana ContentValues values = new ContentValues(); 985f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana values.put(EXTRAS_VALUE, value); 986f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (1 != db.update(TABLE_EXTRAS, values, EXTRAS_ID + "=" + extrasId, null)) { 987f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return; 988f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 989ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 990f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 99104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani writeUserDataIntoCacheLocked(accounts, db, account, key, value); 992f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.setTransactionSuccessful(); 993f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } finally { 994f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.endTransaction(); 995603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 996603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 997603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 998603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 999d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private void onResult(IAccountManagerResponse response, Bundle result) { 100056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (result == null) { 100156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.e(TAG, "the result is unexpectedly null", new Exception()); 100256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 100356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 100456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, getClass().getSimpleName() + " calling onResult() on response " 100556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + response); 100656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 1007d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana try { 1008d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana response.onResult(result); 1009d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } catch (RemoteException e) { 1010d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana // if the caller is dead then there is no one to care about remote 1011d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana // exceptions 1012d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 1013d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Log.v(TAG, "failure while notifying response", e); 1014d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1015d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1016d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1017d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 1018d9640ec712806508877868d08aafaa2d715ff441Fred Quintana public void getAuthTokenLabel(IAccountManagerResponse response, final String accountType, 1019d9640ec712806508877868d08aafaa2d715ff441Fred Quintana final String authTokenType) 1020d9640ec712806508877868d08aafaa2d715ff441Fred Quintana throws RemoteException { 1021d9640ec712806508877868d08aafaa2d715ff441Fred Quintana if (accountType == null) throw new IllegalArgumentException("accountType is null"); 10225f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null"); 10235f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache 1024d9640ec712806508877868d08aafaa2d715ff441Fred Quintana final int callingUid = getCallingUid(); 1025d9640ec712806508877868d08aafaa2d715ff441Fred Quintana clearCallingIdentity(); 1026d9640ec712806508877868d08aafaa2d715ff441Fred Quintana if (callingUid != android.os.Process.SYSTEM_UID) { 1027d9640ec712806508877868d08aafaa2d715ff441Fred Quintana throw new SecurityException("can only call from system"); 1028d9640ec712806508877868d08aafaa2d715ff441Fred Quintana } 1029f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackborn UserAccounts accounts = getUserAccounts(UserHandle.getUserId(callingUid)); 10305f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache long identityToken = clearCallingIdentity(); 10315f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache try { 1032d9640ec712806508877868d08aafaa2d715ff441Fred Quintana new Session(accounts, response, accountType, false, 10335f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache false /* stripAuthTokenFromResult */) { 10345f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache protected String toDebugString(long now) { 10355f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache return super.toDebugString(now) + ", getAuthTokenLabel" 1036d9640ec712806508877868d08aafaa2d715ff441Fred Quintana + ", " + accountType 10375f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache + ", authTokenType " + authTokenType; 10385f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache } 10395f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache 10405f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache public void run() throws RemoteException { 10415f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache mAuthenticator.getAuthTokenLabel(this, authTokenType); 10425f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache } 10435f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache 10445f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache public void onResult(Bundle result) { 10455f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache if (result != null) { 10465f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache String label = result.getString(AccountManager.KEY_AUTH_TOKEN_LABEL); 10475f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache Bundle bundle = new Bundle(); 10485f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache bundle.putString(AccountManager.KEY_AUTH_TOKEN_LABEL, label); 10495f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache super.onResult(bundle); 10505f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache return; 10515f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache } else { 10525f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache super.onResult(result); 10535f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache } 10545f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache } 10555f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache }.bind(); 10565f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache } finally { 10575f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache restoreCallingIdentity(identityToken); 10585f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache } 10595f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache } 10605f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache 1061a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void getAuthToken(IAccountManagerResponse response, final Account account, 1062a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana final String authTokenType, final boolean notifyOnAuthFailure, 1063c6684f9e9790e92960504e9b32f20f27003d9f37Costin Manolache final boolean expectActivityLaunch, Bundle loginOptionsIn) { 106456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 106556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "getAuthToken: " + account 106656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", response " + response 106756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", authTokenType " + authTokenType 106856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", notifyOnAuthFailure " + notifyOnAuthFailure 106956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", expectActivityLaunch " + expectActivityLaunch 107056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 107156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 107256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 1073382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (response == null) throw new IllegalArgumentException("response is null"); 1074382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 1075382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null"); 1076d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkBinderPermission(Manifest.permission.USE_CREDENTIALS); 10774120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn final UserAccounts accounts = getUserAccountsForCaller(); 10786ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey final RegisteredServicesCache.ServiceInfo<AuthenticatorDescription> authenticatorInfo; 10796ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey authenticatorInfo = mAuthenticatorCache.getServiceInfo( 10806ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey AuthenticatorDescription.newKey(account.type), accounts.userId); 1081a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache final boolean customTokens = 1082a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache authenticatorInfo != null && authenticatorInfo.type.customTokens; 1083a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache 1084a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache // skip the check if customTokens 1085b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache final int callerUid = Binder.getCallingUid(); 1086a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache final boolean permissionGranted = customTokens || 1087a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache permissionIsGranted(account, authTokenType, callerUid); 1088a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache 1089c6684f9e9790e92960504e9b32f20f27003d9f37Costin Manolache final Bundle loginOptions = (loginOptionsIn == null) ? new Bundle() : 1090c6684f9e9790e92960504e9b32f20f27003d9f37Costin Manolache loginOptionsIn; 1091b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache // let authenticator know the identity of the caller 1092b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache loginOptions.putInt(AccountManager.KEY_CALLER_UID, callerUid); 1093b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache loginOptions.putInt(AccountManager.KEY_CALLER_PID, Binder.getCallingPid()); 1094b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache if (notifyOnAuthFailure) { 1095b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache loginOptions.putBoolean(AccountManager.KEY_NOTIFY_ON_FAILURE, true); 1096a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache } 10976ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey 109826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 109926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 1100d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana // if the caller has permission, do the peek. otherwise go the more expensive 1101d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana // route of starting a Session 1102a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache if (!customTokens && permissionGranted) { 110304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani String authToken = readAuthTokenInternal(accounts, account, authTokenType); 1104d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (authToken != null) { 110526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana Bundle result = new Bundle(); 1106f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana result.putString(AccountManager.KEY_AUTHTOKEN, authToken); 1107f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name); 1108f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana result.putString(AccountManager.KEY_ACCOUNT_TYPE, account.type); 1109d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana onResult(response, result); 1110d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana return; 1111a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1112a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1113603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 111404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani new Session(accounts, response, account.type, expectActivityLaunch, 11158570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana false /* stripAuthTokenFromResult */) { 111626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana protected String toDebugString(long now) { 111726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana if (loginOptions != null) loginOptions.keySet(); 111826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana return super.toDebugString(now) + ", getAuthToken" 111926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana + ", " + account 112026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana + ", authTokenType " + authTokenType 112126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana + ", loginOptions " + loginOptions 112226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana + ", notifyOnAuthFailure " + notifyOnAuthFailure; 112326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1124a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 112526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana public void run() throws RemoteException { 1126d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana // If the caller doesn't have permission then create and return the 1127d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana // "grant permission" intent instead of the "getAuthToken" intent. 1128d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (!permissionGranted) { 1129d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana mAuthenticator.getAuthTokenLabel(this, authTokenType); 1130d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } else { 1131d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana mAuthenticator.getAuthToken(this, account, authTokenType, loginOptions); 1132d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 113326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1134a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 113526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana public void onResult(Bundle result) { 113626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana if (result != null) { 1137f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana if (result.containsKey(AccountManager.KEY_AUTH_TOKEN_LABEL)) { 1138d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Intent intent = newGrantCredentialsPermissionIntent(account, callerUid, 1139d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana new AccountAuthenticatorResponse(this), 1140d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana authTokenType, 1141f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana result.getString(AccountManager.KEY_AUTH_TOKEN_LABEL)); 1142d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Bundle bundle = new Bundle(); 1143f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana bundle.putParcelable(AccountManager.KEY_INTENT, intent); 1144d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana onResult(bundle); 1145d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana return; 1146d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1147f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana String authToken = result.getString(AccountManager.KEY_AUTHTOKEN); 114826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana if (authToken != null) { 1149f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana String name = result.getString(AccountManager.KEY_ACCOUNT_NAME); 1150f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana String type = result.getString(AccountManager.KEY_ACCOUNT_TYPE); 115126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana if (TextUtils.isEmpty(type) || TextUtils.isEmpty(name)) { 1152f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana onError(AccountManager.ERROR_CODE_INVALID_RESPONSE, 115326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana "the type and name should not be empty"); 115426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana return; 115526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1156a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache if (!customTokens) { 115704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani saveAuthTokenToDatabase(mAccounts, new Account(name, type), 1158a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache authTokenType, authToken); 1159a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache } 1160a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1161603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1162f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana Intent intent = result.getParcelable(AccountManager.KEY_INTENT); 1163d606045070dcf6a011e49a7711d2f17d8f2de8c1Costin Manolache if (intent != null && notifyOnAuthFailure && !customTokens) { 116404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani doNotification(mAccounts, 1165f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana account, result.getString(AccountManager.KEY_AUTH_FAILED_MESSAGE), 11664120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn intent, accounts.userId); 116726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1168a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 116926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana super.onResult(result); 1170a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 117126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana }.bind(); 117226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 117326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 117426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1175603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1176603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 11774120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn private void createNoCredentialsPermissionNotification(Account account, Intent intent, 11784120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn int userId) { 1179d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana int uid = intent.getIntExtra( 1180d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana GrantCredentialsPermissionActivity.EXTRAS_REQUESTING_UID, -1); 1181d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana String authTokenType = intent.getStringExtra( 1182d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana GrantCredentialsPermissionActivity.EXTRAS_AUTH_TOKEN_TYPE); 1183d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana String authTokenLabel = intent.getStringExtra( 1184d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana GrantCredentialsPermissionActivity.EXTRAS_AUTH_TOKEN_LABEL); 1185d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 1186d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Notification n = new Notification(android.R.drawable.stat_sys_warning, null, 1187d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 0 /* when */); 1188ee452ee5359cdfa3c3fbf6783722d3aaa2ec5ca6Eric Fischer final String titleAndSubtitle = 1189ee452ee5359cdfa3c3fbf6783722d3aaa2ec5ca6Eric Fischer mContext.getString(R.string.permission_request_notification_with_subtitle, 1190ee452ee5359cdfa3c3fbf6783722d3aaa2ec5ca6Eric Fischer account.name); 1191ee452ee5359cdfa3c3fbf6783722d3aaa2ec5ca6Eric Fischer final int index = titleAndSubtitle.indexOf('\n'); 119285e7279d9cc1ee8e4dd1f993a9e61a9eb547ecbcCostin Manolache String title = titleAndSubtitle; 119385e7279d9cc1ee8e4dd1f993a9e61a9eb547ecbcCostin Manolache String subtitle = ""; 119485e7279d9cc1ee8e4dd1f993a9e61a9eb547ecbcCostin Manolache if (index > 0) { 119585e7279d9cc1ee8e4dd1f993a9e61a9eb547ecbcCostin Manolache title = titleAndSubtitle.substring(0, index); 119685e7279d9cc1ee8e4dd1f993a9e61a9eb547ecbcCostin Manolache subtitle = titleAndSubtitle.substring(index + 1); 119785e7279d9cc1ee8e4dd1f993a9e61a9eb547ecbcCostin Manolache } 119850cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn UserHandle user = new UserHandle(userId); 11994120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn n.setLatestEventInfo(mContext, title, subtitle, 12004120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn PendingIntent.getActivityAsUser(mContext, 0, intent, 120150cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn PendingIntent.FLAG_CANCEL_CURRENT, null, user)); 120250cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn installNotification(getCredentialPermissionNotificationId( 120350cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn account, authTokenType, uid), n, user); 1204d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1205d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 12065f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache private Intent newGrantCredentialsPermissionIntent(Account account, int uid, 12075f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache AccountAuthenticatorResponse response, String authTokenType, String authTokenLabel) { 1208d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 1209d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Intent intent = new Intent(mContext, GrantCredentialsPermissionActivity.class); 121046703b099516c383a6882815bcf9cd4df0ec538dBrian Carlstrom // See FLAG_ACTIVITY_NEW_TASK docs for limitations and benefits of the flag. 12119ec17366c17efd14c643ee88fa1132ab05197349Costin Manolache // Since it was set in Eclair+ we can't change it without breaking apps using 12129ec17366c17efd14c643ee88fa1132ab05197349Costin Manolache // the intent from a non-Activity context. 12139ec17366c17efd14c643ee88fa1132ab05197349Costin Manolache intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 1214d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana intent.addCategory( 1215d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana String.valueOf(getCredentialPermissionNotificationId(account, authTokenType, uid))); 12165f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache 1217d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana intent.putExtra(GrantCredentialsPermissionActivity.EXTRAS_ACCOUNT, account); 1218d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana intent.putExtra(GrantCredentialsPermissionActivity.EXTRAS_AUTH_TOKEN_TYPE, authTokenType); 1219d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana intent.putExtra(GrantCredentialsPermissionActivity.EXTRAS_RESPONSE, response); 1220d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana intent.putExtra(GrantCredentialsPermissionActivity.EXTRAS_REQUESTING_UID, uid); 12215f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache 1222d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana return intent; 1223d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1224d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 1225d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private Integer getCredentialPermissionNotificationId(Account account, String authTokenType, 1226d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana int uid) { 1227d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Integer id; 1228f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackborn UserAccounts accounts = getUserAccounts(UserHandle.getUserId(uid)); 122904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.credentialsPermissionNotificationIds) { 1230d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana final Pair<Pair<Account, String>, Integer> key = 1231d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana new Pair<Pair<Account, String>, Integer>( 1232d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana new Pair<Account, String>(account, authTokenType), uid); 123304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani id = accounts.credentialsPermissionNotificationIds.get(key); 1234d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (id == null) { 1235d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana id = mNotificationIds.incrementAndGet(); 123604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.credentialsPermissionNotificationIds.put(key, id); 1237d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1238d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1239d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana return id; 1240d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1241d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 124204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private Integer getSigninRequiredNotificationId(UserAccounts accounts, Account account) { 1243d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Integer id; 124404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.signinRequiredNotificationIds) { 124504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani id = accounts.signinRequiredNotificationIds.get(account); 1246d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (id == null) { 1247d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana id = mNotificationIds.incrementAndGet(); 124804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.signinRequiredNotificationIds.put(account, id); 1249d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1250d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1251d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana return id; 1252d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1253d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 12543326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana public void addAcount(final IAccountManagerResponse response, final String accountType, 12553326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana final String authTokenType, final String[] requiredFeatures, 1256b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache final boolean expectActivityLaunch, final Bundle optionsIn) { 125756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 125856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "addAccount: accountType " + accountType 125956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", response " + response 126056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", authTokenType " + authTokenType 126156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", requiredFeatures " + stringArrayToString(requiredFeatures) 126256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", expectActivityLaunch " + expectActivityLaunch 126356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 126456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 126556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 1266382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (response == null) throw new IllegalArgumentException("response is null"); 1267382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (accountType == null) throw new IllegalArgumentException("accountType is null"); 1268d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkManageAccountsPermission(); 1269b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache 127004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 1271b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache final int pid = Binder.getCallingPid(); 1272b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache final int uid = Binder.getCallingUid(); 1273b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache final Bundle options = (optionsIn == null) ? new Bundle() : optionsIn; 1274b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache options.putInt(AccountManager.KEY_CALLER_UID, uid); 1275b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache options.putInt(AccountManager.KEY_CALLER_PID, pid); 1276b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache 127726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 127826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 127904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani new Session(accounts, response, accountType, expectActivityLaunch, 12808570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana true /* stripAuthTokenFromResult */) { 128126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana public void run() throws RemoteException { 12823348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache mAuthenticator.addAccount(this, mAccountType, authTokenType, requiredFeatures, 12833326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana options); 128426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1285a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 128626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana protected String toDebugString(long now) { 128726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana return super.toDebugString(now) + ", addAccount" 12883326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + ", accountType " + accountType 12893326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + ", requiredFeatures " 12903326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + (requiredFeatures != null 12913326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana ? TextUtils.join(",", requiredFeatures) 12923326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana : null); 129326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 129426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana }.bind(); 129526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 129626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 129726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1298603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1299603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 13002c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani @Override 13012c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani public void confirmCredentialsAsUser(IAccountManagerResponse response, 13022c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani final Account account, final Bundle options, final boolean expectActivityLaunch, 13032c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani int userId) { 13042c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani // Only allow the system process to read accounts of other users 13052c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani if (userId != UserHandle.getCallingUserId() 13062c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani && Binder.getCallingUid() != android.os.Process.myUid()) { 13072c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani throw new SecurityException("User " + UserHandle.getCallingUserId() 13082c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani + " trying to confirm account credentials for " + userId); 13092c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani } 13102c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani 131156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 131256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "confirmCredentials: " + account 131356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", response " + response 131456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", expectActivityLaunch " + expectActivityLaunch 131556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 131656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 131756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 1318382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (response == null) throw new IllegalArgumentException("response is null"); 1319382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 1320d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkManageAccountsPermission(); 13212c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani UserAccounts accounts = getUserAccounts(userId); 132226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 132326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 132404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani new Session(accounts, response, account.type, expectActivityLaunch, 13258570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana true /* stripAuthTokenFromResult */) { 132626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana public void run() throws RemoteException { 1327f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana mAuthenticator.confirmCredentials(this, account, options); 132826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 132926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana protected String toDebugString(long now) { 133026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana return super.toDebugString(now) + ", confirmCredentials" 133126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana + ", " + account; 133226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 133326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana }.bind(); 133426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 133526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 133626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1337603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1338603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1339a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void updateCredentials(IAccountManagerResponse response, final Account account, 1340a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana final String authTokenType, final boolean expectActivityLaunch, 1341a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana final Bundle loginOptions) { 134256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 134356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "updateCredentials: " + account 134456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", response " + response 134556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", authTokenType " + authTokenType 134656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", expectActivityLaunch " + expectActivityLaunch 134756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 134856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 134956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 1350382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (response == null) throw new IllegalArgumentException("response is null"); 1351382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 1352382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null"); 1353d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkManageAccountsPermission(); 135404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 135526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 135626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 135704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani new Session(accounts, response, account.type, expectActivityLaunch, 13588570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana true /* stripAuthTokenFromResult */) { 135926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana public void run() throws RemoteException { 136026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana mAuthenticator.updateCredentials(this, account, authTokenType, loginOptions); 136126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 136226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana protected String toDebugString(long now) { 136326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana if (loginOptions != null) loginOptions.keySet(); 136426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana return super.toDebugString(now) + ", updateCredentials" 136526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana + ", " + account 136626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana + ", authTokenType " + authTokenType 136726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana + ", loginOptions " + loginOptions; 136826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 136926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana }.bind(); 137026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 137126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 137226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1373603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1374603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1375a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void editProperties(IAccountManagerResponse response, final String accountType, 1376a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana final boolean expectActivityLaunch) { 137756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 137856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "editProperties: accountType " + accountType 137956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", response " + response 138056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", expectActivityLaunch " + expectActivityLaunch 138156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 138256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 138356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 1384382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (response == null) throw new IllegalArgumentException("response is null"); 1385382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (accountType == null) throw new IllegalArgumentException("accountType is null"); 1386d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkManageAccountsPermission(); 138704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 138826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 138926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 139004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani new Session(accounts, response, accountType, expectActivityLaunch, 13918570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana true /* stripAuthTokenFromResult */) { 139226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana public void run() throws RemoteException { 139326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana mAuthenticator.editProperties(this, mAccountType); 139426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 139526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana protected String toDebugString(long now) { 139626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana return super.toDebugString(now) + ", editProperties" 139726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana + ", accountType " + accountType; 139826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 139926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana }.bind(); 140026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 140126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 140226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1403603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1404603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 14053326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana private class GetAccountsByTypeAndFeatureSession extends Session { 14063326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana private final String[] mFeatures; 14073326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana private volatile Account[] mAccountsOfType = null; 14083326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana private volatile ArrayList<Account> mAccountsWithFeatures = null; 14093326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana private volatile int mCurrentAccount = 0; 14103326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 141104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani public GetAccountsByTypeAndFeatureSession(UserAccounts accounts, 141204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani IAccountManagerResponse response, String type, String[] features) { 141304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani super(accounts, response, type, false /* expectActivityLaunch */, 14148570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana true /* stripAuthTokenFromResult */); 14153326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana mFeatures = features; 14163326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 14173326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 14183326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana public void run() throws RemoteException { 141904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (mAccounts.cacheLock) { 142004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani mAccountsOfType = getAccountsFromCacheLocked(mAccounts, mAccountType); 1421f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 14223326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana // check whether each account matches the requested features 14233326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana mAccountsWithFeatures = new ArrayList<Account>(mAccountsOfType.length); 14243326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana mCurrentAccount = 0; 14253326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 14263326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana checkAccount(); 14273326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 14283326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 14293326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana public void checkAccount() { 14303326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana if (mCurrentAccount >= mAccountsOfType.length) { 14313326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana sendResult(); 14323326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana return; 14333326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 14343326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 143529e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana final IAccountAuthenticator accountAuthenticator = mAuthenticator; 143629e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana if (accountAuthenticator == null) { 143729e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana // It is possible that the authenticator has died, which is indicated by 143829e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana // mAuthenticator being set to null. If this happens then just abort. 143929e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana // There is no need to send back a result or error in this case since 144029e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana // that already happened when mAuthenticator was cleared. 144129e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 144229e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana Log.v(TAG, "checkAccount: aborting session since we are no longer" 144329e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana + " connected to the authenticator, " + toDebugString()); 144429e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana } 144529e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana return; 144629e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana } 14473326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana try { 144829e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana accountAuthenticator.hasFeatures(this, mAccountsOfType[mCurrentAccount], mFeatures); 14493326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } catch (RemoteException e) { 1450f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana onError(AccountManager.ERROR_CODE_REMOTE_EXCEPTION, "remote exception"); 1451a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1452603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1453603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 14543326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana public void onResult(Bundle result) { 14553326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana mNumResults++; 14563326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana if (result == null) { 1457f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana onError(AccountManager.ERROR_CODE_INVALID_RESPONSE, "null bundle"); 14583326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana return; 14593326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 1460f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana if (result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT, false)) { 14613326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana mAccountsWithFeatures.add(mAccountsOfType[mCurrentAccount]); 14623326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 14633326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana mCurrentAccount++; 14643326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana checkAccount(); 1465a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 14663326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 14673326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana public void sendResult() { 14683326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana IAccountManagerResponse response = getResponseAndClose(); 14693326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana if (response != null) { 14703326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana try { 14713326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana Account[] accounts = new Account[mAccountsWithFeatures.size()]; 14723326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana for (int i = 0; i < accounts.length; i++) { 14733326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana accounts[i] = mAccountsWithFeatures.get(i); 14743326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 147556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 147656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, getClass().getSimpleName() + " calling onResult() on response " 147756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + response); 147856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 14793326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana Bundle result = new Bundle(); 1480f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana result.putParcelableArray(AccountManager.KEY_ACCOUNTS, accounts); 14813326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana response.onResult(result); 14823326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } catch (RemoteException e) { 14833326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana // if the caller is dead then there is no one to care about remote exceptions 14843326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 14853326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana Log.v(TAG, "failure while notifying response", e); 14863326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 14873326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 14883326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 14893326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 14903326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 14913326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 14923326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana protected String toDebugString(long now) { 14933326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana return super.toDebugString(now) + ", getAccountsByTypeAndFeatures" 14943326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + ", " + (mFeatures != null ? TextUtils.join(",", mFeatures) : null); 14953326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 14963326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 1497ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 149804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani /** 149904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani * Returns the accounts for a specific user 150004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani * @hide 150104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani */ 150204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani public Account[] getAccounts(int userId) { 150304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani checkReadAccountsPermission(); 150404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccounts(userId); 150504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani long identityToken = clearCallingIdentity(); 150604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani try { 150704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 150804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani return getAccountsFromCacheLocked(accounts, null); 150904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 151004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } finally { 151104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani restoreCallingIdentity(identityToken); 151204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 151304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 151404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani 1515f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani /** 15166ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey * Returns accounts for all running users. 15176ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey * 1518f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani * @hide 1519f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani */ 15206ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey public AccountAndUser[] getRunningAccounts() { 15216ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey final int[] runningUserIds; 15226ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey try { 15236ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey runningUserIds = ActivityManagerNative.getDefault().getRunningUserIds(); 15246ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey } catch (RemoteException e) { 15256ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey // Running in system_server; should never happen 15266ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey throw new RuntimeException(e); 15276ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey } 15286eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey return getAccounts(runningUserIds); 15296eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey } 15306eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey 15316eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey /** {@hide} */ 15326eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey public AccountAndUser[] getAllAccounts() { 15336eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey final List<UserInfo> users = getUserManager().getUsers(); 15346eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey final int[] userIds = new int[users.size()]; 15356eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey for (int i = 0; i < userIds.length; i++) { 15366eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey userIds[i] = users.get(i).id; 15376eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey } 15386eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey return getAccounts(userIds); 15396eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey } 15406ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey 15416eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey private AccountAndUser[] getAccounts(int[] userIds) { 15426ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey final ArrayList<AccountAndUser> runningAccounts = Lists.newArrayList(); 15436ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey synchronized (mUsers) { 15446eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey for (int userId : userIds) { 15456ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey UserAccounts userAccounts = getUserAccounts(userId); 1546f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani if (userAccounts == null) continue; 1547f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani synchronized (userAccounts.cacheLock) { 1548f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani Account[] accounts = getAccountsFromCacheLocked(userAccounts, null); 1549f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani for (int a = 0; a < accounts.length; a++) { 15506ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey runningAccounts.add(new AccountAndUser(accounts[a], userId)); 1551f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani } 1552f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani } 1553f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani } 1554f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani } 15556ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey 15566ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey AccountAndUser[] accountsArray = new AccountAndUser[runningAccounts.size()]; 15576ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey return runningAccounts.toArray(accountsArray); 1558f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani } 1559f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani 15602c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani @Override 15612c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani public Account[] getAccountsAsUser(String type, int userId) { 15622c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani // Only allow the system process to read accounts of other users 15632c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani if (userId != UserHandle.getCallingUserId() 15642c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani && Binder.getCallingUid() != android.os.Process.myUid()) { 15652c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani throw new SecurityException("User " + UserHandle.getCallingUserId() 15662c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani + " trying to get account for " + userId); 15672c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani } 15682c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani 156956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 157056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "getAccounts: accountType " + type 157156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 157256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 157356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 1574ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana checkReadAccountsPermission(); 15752c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani UserAccounts accounts = getUserAccounts(userId); 1576ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana long identityToken = clearCallingIdentity(); 1577ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana try { 157804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 157904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani return getAccountsFromCacheLocked(accounts, type); 1580f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 1581ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } finally { 1582ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana restoreCallingIdentity(identityToken); 1583ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 1584ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 1585ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 15862c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani @Override 15872c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani public Account[] getAccounts(String type) { 15882c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani return getAccountsAsUser(type, UserHandle.getCallingUserId()); 15892c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani } 15902c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani 1591ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana public void getAccountsByFeatures(IAccountManagerResponse response, 15923326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana String type, String[] features) { 159356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 159456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "getAccounts: accountType " + type 159556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", response " + response 159656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", features " + stringArrayToString(features) 159756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 159856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 159956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 1600382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (response == null) throw new IllegalArgumentException("response is null"); 1601382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (type == null) throw new IllegalArgumentException("accountType is null"); 1602d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkReadAccountsPermission(); 160304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts userAccounts = getUserAccountsForCaller(); 16043326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana long identityToken = clearCallingIdentity(); 16053326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana try { 1606ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana if (features == null || features.length == 0) { 1607f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana Account[] accounts; 160804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (userAccounts.cacheLock) { 160904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts = getAccountsFromCacheLocked(userAccounts, type); 1610f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 1611d4a9d6c42bb412e27a8383aaacd051419d98a662Fred Quintana Bundle result = new Bundle(); 1612d4a9d6c42bb412e27a8383aaacd051419d98a662Fred Quintana result.putParcelableArray(AccountManager.KEY_ACCOUNTS, accounts); 1613d4a9d6c42bb412e27a8383aaacd051419d98a662Fred Quintana onResult(response, result); 1614ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana return; 1615ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 161604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani new GetAccountsByTypeAndFeatureSession(userAccounts, response, type, features).bind(); 16173326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } finally { 16183326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana restoreCallingIdentity(identityToken); 16193326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 16203326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 16213326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 1622f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana private long getAccountIdLocked(SQLiteDatabase db, Account account) { 1623603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana Cursor cursor = db.query(TABLE_ACCOUNTS, new String[]{ACCOUNTS_ID}, 1624ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana "name=? AND type=?", new String[]{account.name, account.type}, null, null, null); 1625603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana try { 1626603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana if (cursor.moveToNext()) { 1627603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana return cursor.getLong(0); 1628603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1629603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana return -1; 1630603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } finally { 1631603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana cursor.close(); 1632603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1633603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1634603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1635f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana private long getExtrasIdLocked(SQLiteDatabase db, long accountId, String key) { 1636603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana Cursor cursor = db.query(TABLE_EXTRAS, new String[]{EXTRAS_ID}, 1637603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana EXTRAS_ACCOUNTS_ID + "=" + accountId + " AND " + EXTRAS_KEY + "=?", 1638603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana new String[]{key}, null, null, null); 1639603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana try { 1640603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana if (cursor.moveToNext()) { 1641603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana return cursor.getLong(0); 1642603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1643603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana return -1; 1644603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } finally { 1645603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana cursor.close(); 1646603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1647603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1648603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1649a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana private abstract class Session extends IAccountAuthenticatorResponse.Stub 1650b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana implements IBinder.DeathRecipient, ServiceConnection { 1651603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana IAccountManagerResponse mResponse; 1652603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana final String mAccountType; 1653a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana final boolean mExpectActivityLaunch; 1654a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana final long mCreationTime; 1655a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 16563326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana public int mNumResults = 0; 1657a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana private int mNumRequestContinued = 0; 1658a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana private int mNumErrors = 0; 1659a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 1660603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1661603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana IAccountAuthenticator mAuthenticator = null; 1662603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 16638570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana private final boolean mStripAuthTokenFromResult; 166404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani protected final UserAccounts mAccounts; 16658570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana 166604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani public Session(UserAccounts accounts, IAccountManagerResponse response, String accountType, 16678570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana boolean expectActivityLaunch, boolean stripAuthTokenFromResult) { 1668603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana super(); 1669a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (response == null) throw new IllegalArgumentException("response is null"); 16703326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana if (accountType == null) throw new IllegalArgumentException("accountType is null"); 167104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani mAccounts = accounts; 16728570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana mStripAuthTokenFromResult = stripAuthTokenFromResult; 1673603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mResponse = response; 1674603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mAccountType = accountType; 1675a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana mExpectActivityLaunch = expectActivityLaunch; 1676a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana mCreationTime = SystemClock.elapsedRealtime(); 1677a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana synchronized (mSessions) { 1678a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana mSessions.put(toString(), this); 1679a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1680a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana try { 1681a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana response.asBinder().linkToDeath(this, 0 /* flags */); 1682a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } catch (RemoteException e) { 1683a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana mResponse = null; 1684a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana binderDied(); 1685a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1686603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1687603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1688a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana IAccountManagerResponse getResponseAndClose() { 1689603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana if (mResponse == null) { 1690603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana // this session has already been closed 1691603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana return null; 1692603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1693a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana IAccountManagerResponse response = mResponse; 1694a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana close(); // this clears mResponse so we need to save the response before this call 1695a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana return response; 1696a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1697a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 1698a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana private void close() { 1699a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana synchronized (mSessions) { 1700a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (mSessions.remove(toString()) == null) { 1701a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana // the session was already closed, so bail out now 1702a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana return; 1703a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1704a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1705a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (mResponse != null) { 1706a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana // stop listening for response deaths 1707a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana mResponse.asBinder().unlinkToDeath(this, 0 /* flags */); 1708a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 1709a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana // clear this so that we don't accidentally send any further results 1710a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana mResponse = null; 1711a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1712603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana cancelTimeout(); 1713603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana unbind(); 1714a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1715a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 1716a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void binderDied() { 1717603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mResponse = null; 1718a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana close(); 1719a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1720a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 1721a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana protected String toDebugString() { 1722a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana return toDebugString(SystemClock.elapsedRealtime()); 1723a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1724a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 1725a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana protected String toDebugString(long now) { 1726a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana return "Session: expectLaunch " + mExpectActivityLaunch 1727a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + ", connected " + (mAuthenticator != null) 1728a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + ", stats (" + mNumResults + "/" + mNumRequestContinued 1729a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + "/" + mNumErrors + ")" 1730a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + ", lifetime " + ((now - mCreationTime) / 1000.0); 1731603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1732603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1733603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana void bind() { 1734a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 1735a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana Log.v(TAG, "initiating bind to authenticator type " + mAccountType); 1736a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1737b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana if (!bindToAuthenticator(mAccountType)) { 1738a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana Log.d(TAG, "bind attempt failed for " + toDebugString()); 1739f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana onError(AccountManager.ERROR_CODE_REMOTE_EXCEPTION, "bind failure"); 1740603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1741603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1742603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1743603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private void unbind() { 1744603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana if (mAuthenticator != null) { 1745603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mAuthenticator = null; 1746b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana mContext.unbindService(this); 1747603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1748603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1749603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1750603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public void scheduleTimeout() { 1751603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mMessageHandler.sendMessageDelayed( 1752603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mMessageHandler.obtainMessage(MESSAGE_TIMED_OUT, this), TIMEOUT_DELAY_MS); 1753603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1754603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1755603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public void cancelTimeout() { 1756603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mMessageHandler.removeMessages(MESSAGE_TIMED_OUT, this); 1757603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1758603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1759b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana public void onServiceConnected(ComponentName name, IBinder service) { 1760603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mAuthenticator = IAccountAuthenticator.Stub.asInterface(service); 1761a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana try { 1762a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana run(); 1763a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } catch (RemoteException e) { 1764f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana onError(AccountManager.ERROR_CODE_REMOTE_EXCEPTION, 1765a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana "remote exception"); 1766a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1767603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1768603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1769b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana public void onServiceDisconnected(ComponentName name) { 1770a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana mAuthenticator = null; 1771a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana IAccountManagerResponse response = getResponseAndClose(); 1772603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana if (response != null) { 1773166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana try { 1774166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana response.onError(AccountManager.ERROR_CODE_REMOTE_EXCEPTION, 1775166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana "disconnected"); 1776166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana } catch (RemoteException e) { 1777166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 1778166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana Log.v(TAG, "Session.onServiceDisconnected: " 1779166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana + "caught RemoteException while responding", e); 1780166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana } 1781166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana } 1782603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1783603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1784603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1785b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana public abstract void run() throws RemoteException; 1786b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana 1787603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public void onTimedOut() { 1788a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana IAccountManagerResponse response = getResponseAndClose(); 1789603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana if (response != null) { 1790166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana try { 1791166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana response.onError(AccountManager.ERROR_CODE_REMOTE_EXCEPTION, 1792166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana "timeout"); 1793166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana } catch (RemoteException e) { 1794166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 1795166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana Log.v(TAG, "Session.onTimedOut: caught RemoteException while responding", 1796166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana e); 1797166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana } 1798166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana } 1799603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1800603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1801603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1802a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void onResult(Bundle result) { 1803a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana mNumResults++; 1804f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana if (result != null && !TextUtils.isEmpty(result.getString(AccountManager.KEY_AUTHTOKEN))) { 1805f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana String accountName = result.getString(AccountManager.KEY_ACCOUNT_NAME); 1806f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana String accountType = result.getString(AccountManager.KEY_ACCOUNT_TYPE); 1807d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (!TextUtils.isEmpty(accountName) && !TextUtils.isEmpty(accountType)) { 1808d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Account account = new Account(accountName, accountType); 180950cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn cancelNotification(getSigninRequiredNotificationId(mAccounts, account), 181050cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn new UserHandle(mAccounts.userId)); 1811d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1812603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1813a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana IAccountManagerResponse response; 1814a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (mExpectActivityLaunch && result != null 1815f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana && result.containsKey(AccountManager.KEY_INTENT)) { 1816a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana response = mResponse; 1817a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } else { 1818a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana response = getResponseAndClose(); 1819603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1820603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana if (response != null) { 1821603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana try { 1822a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (result == null) { 182356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 182456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, getClass().getSimpleName() 182556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + " calling onError() on response " + response); 182656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 1827f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana response.onError(AccountManager.ERROR_CODE_INVALID_RESPONSE, 1828a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana "null bundle returned"); 1829a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } else { 18308570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana if (mStripAuthTokenFromResult) { 18318570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana result.remove(AccountManager.KEY_AUTHTOKEN); 18328570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana } 183356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 183456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, getClass().getSimpleName() 183556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + " calling onResult() on response " + response); 183656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 1837a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana response.onResult(result); 1838a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1839603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } catch (RemoteException e) { 1840a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana // if the caller is dead then there is no one to care about remote exceptions 1841a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 1842a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana Log.v(TAG, "failure while notifying response", e); 1843a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1844603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1845603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1846603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1847603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1848a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void onRequestContinued() { 1849a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana mNumRequestContinued++; 1850603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1851603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1852603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public void onError(int errorCode, String errorMessage) { 1853a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana mNumErrors++; 1854a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana IAccountManagerResponse response = getResponseAndClose(); 1855a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (response != null) { 1856a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 185756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, getClass().getSimpleName() 185856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + " calling onError() on response " + response); 1859a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1860a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana try { 1861a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana response.onError(errorCode, errorMessage); 1862a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } catch (RemoteException e) { 1863a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 1864a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana Log.v(TAG, "Session.onError: caught RemoteException while responding", e); 1865a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1866a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1867a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } else { 1868a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 1869a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana Log.v(TAG, "Session.onError: already closed"); 1870a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1871603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1872603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1873b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana 1874b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana /** 1875b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana * find the component name for the authenticator and initiate a bind 1876b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana * if no authenticator or the bind fails then return false, otherwise return true 1877b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana */ 1878b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana private boolean bindToAuthenticator(String authenticatorType) { 18796ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey final AccountAuthenticatorCache.ServiceInfo<AuthenticatorDescription> authenticatorInfo; 18806ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey authenticatorInfo = mAuthenticatorCache.getServiceInfo( 18816ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey AuthenticatorDescription.newKey(authenticatorType), mAccounts.userId); 1882b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana if (authenticatorInfo == null) { 1883b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 1884b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana Log.v(TAG, "there is no authenticator for " + authenticatorType 1885b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana + ", bailing out"); 1886b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana } 1887b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana return false; 1888b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana } 1889b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana 1890b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana Intent intent = new Intent(); 1891b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana intent.setAction(AccountManager.ACTION_AUTHENTICATOR_INTENT); 1892b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana intent.setComponent(authenticatorInfo.componentName); 1893b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 1894b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana Log.v(TAG, "performing bindService to " + authenticatorInfo.componentName); 1895b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana } 189634daa75260c9aebe791819ff6134b4c47146c5c0Amith Yamasani if (!mContext.bindService(intent, this, Context.BIND_AUTO_CREATE, mAccounts.userId)) { 1897b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 1898b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana Log.v(TAG, "bindService to " + authenticatorInfo.componentName + " failed"); 1899b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana } 1900b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana return false; 1901b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana } 1902b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana 1903b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana 1904b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana return true; 1905b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana } 1906603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1907603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1908603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private class MessageHandler extends Handler { 1909603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana MessageHandler(Looper looper) { 1910603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana super(looper); 1911603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 19123348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache 1913603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public void handleMessage(Message msg) { 1914603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana switch (msg.what) { 1915603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana case MESSAGE_TIMED_OUT: 1916603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana Session session = (Session)msg.obj; 1917603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana session.onTimedOut(); 1918603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana break; 1919603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1920603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana default: 1921603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana throw new IllegalStateException("unhandled message: " + msg.what); 1922603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1923603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1924603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1925603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 192604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private static String getDatabaseName(int userId) { 192704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani File systemDir = Environment.getSystemSecureDirectory(); 192861f57379ca2c5b6290c8da7548fa17128f7ab24fAmith Yamasani File databaseFile = new File(Environment.getUserSystemDirectory(userId), DATABASE_NAME); 192904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani if (userId == 0) { 1930a23bb38628ac1f5dc4ebe6847faedc424dd5fce1Amith Yamasani // Migrate old file, if it exists, to the new location. 1931a23bb38628ac1f5dc4ebe6847faedc424dd5fce1Amith Yamasani // Make sure the new file doesn't already exist. A dummy file could have been 1932a23bb38628ac1f5dc4ebe6847faedc424dd5fce1Amith Yamasani // accidentally created in the old location, causing the new one to become corrupted 1933a23bb38628ac1f5dc4ebe6847faedc424dd5fce1Amith Yamasani // as well. 193404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani File oldFile = new File(systemDir, DATABASE_NAME); 1935a23bb38628ac1f5dc4ebe6847faedc424dd5fce1Amith Yamasani if (oldFile.exists() && !databaseFile.exists()) { 1936c6b0f99bb31405902b40a96f6491a9adcaaac169Marc Blank // Check for use directory; create if it doesn't exist, else renameTo will fail 193761f57379ca2c5b6290c8da7548fa17128f7ab24fAmith Yamasani File userDir = Environment.getUserSystemDirectory(userId); 1938c6b0f99bb31405902b40a96f6491a9adcaaac169Marc Blank if (!userDir.exists()) { 1939c6b0f99bb31405902b40a96f6491a9adcaaac169Marc Blank if (!userDir.mkdirs()) { 1940c6b0f99bb31405902b40a96f6491a9adcaaac169Marc Blank throw new IllegalStateException("User dir cannot be created: " + userDir); 1941c6b0f99bb31405902b40a96f6491a9adcaaac169Marc Blank } 1942c6b0f99bb31405902b40a96f6491a9adcaaac169Marc Blank } 1943c6b0f99bb31405902b40a96f6491a9adcaaac169Marc Blank if (!oldFile.renameTo(databaseFile)) { 1944c6b0f99bb31405902b40a96f6491a9adcaaac169Marc Blank throw new IllegalStateException("User dir cannot be migrated: " + databaseFile); 1945c6b0f99bb31405902b40a96f6491a9adcaaac169Marc Blank } 194604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 1947a8529f68671a8a118751cb6ad577f44eaf076b96Oscar Montemayor } 194804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani return databaseFile.getPath(); 1949a8529f68671a8a118751cb6ad577f44eaf076b96Oscar Montemayor } 1950a8529f68671a8a118751cb6ad577f44eaf076b96Oscar Montemayor 195104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani static class DatabaseHelper extends SQLiteOpenHelper { 1952a8529f68671a8a118751cb6ad577f44eaf076b96Oscar Montemayor 195304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani public DatabaseHelper(Context context, int userId) { 195404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani super(context, AccountManagerService.getDatabaseName(userId), null, DATABASE_VERSION); 1955603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1956603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1957f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana /** 1958f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana * This call needs to be made while the mCacheLock is held. The way to 1959f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana * ensure this is to get the lock any time a method is called ont the DatabaseHelper 1960f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana * @param db The database. 1961f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana */ 1962603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana @Override 1963603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public void onCreate(SQLiteDatabase db) { 1964603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana db.execSQL("CREATE TABLE " + TABLE_ACCOUNTS + " ( " 1965603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + ACCOUNTS_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " 1966603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + ACCOUNTS_NAME + " TEXT NOT NULL, " 1967603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + ACCOUNTS_TYPE + " TEXT NOT NULL, " 1968603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + ACCOUNTS_PASSWORD + " TEXT, " 1969603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + "UNIQUE(" + ACCOUNTS_NAME + "," + ACCOUNTS_TYPE + "))"); 1970603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1971603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana db.execSQL("CREATE TABLE " + TABLE_AUTHTOKENS + " ( " 1972603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + AUTHTOKENS_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " 1973603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + AUTHTOKENS_ACCOUNTS_ID + " INTEGER NOT NULL, " 1974603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + AUTHTOKENS_TYPE + " TEXT NOT NULL, " 1975603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + AUTHTOKENS_AUTHTOKEN + " TEXT, " 1976603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + "UNIQUE (" + AUTHTOKENS_ACCOUNTS_ID + "," + AUTHTOKENS_TYPE + "))"); 1977603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1978d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana createGrantsTable(db); 1979d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 1980603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana db.execSQL("CREATE TABLE " + TABLE_EXTRAS + " ( " 1981603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + EXTRAS_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " 1982603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + EXTRAS_ACCOUNTS_ID + " INTEGER, " 1983603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + EXTRAS_KEY + " TEXT NOT NULL, " 1984603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + EXTRAS_VALUE + " TEXT, " 1985603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + "UNIQUE(" + EXTRAS_ACCOUNTS_ID + "," + EXTRAS_KEY + "))"); 1986603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1987603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana db.execSQL("CREATE TABLE " + TABLE_META + " ( " 1988603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + META_KEY + " TEXT PRIMARY KEY NOT NULL, " 1989603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + META_VALUE + " TEXT)"); 1990a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 1991d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana createAccountsDeletionTrigger(db); 1992d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1993d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 1994d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private void createAccountsDeletionTrigger(SQLiteDatabase db) { 1995a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana db.execSQL("" 1996a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + " CREATE TRIGGER " + TABLE_ACCOUNTS + "Delete DELETE ON " + TABLE_ACCOUNTS 1997a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + " BEGIN" 1998a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + " DELETE FROM " + TABLE_AUTHTOKENS 1999a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + " WHERE " + AUTHTOKENS_ACCOUNTS_ID + "=OLD." + ACCOUNTS_ID + " ;" 2000a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + " DELETE FROM " + TABLE_EXTRAS 2001a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + " WHERE " + EXTRAS_ACCOUNTS_ID + "=OLD." + ACCOUNTS_ID + " ;" 2002d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + " DELETE FROM " + TABLE_GRANTS 2003d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + " WHERE " + GRANTS_ACCOUNTS_ID + "=OLD." + ACCOUNTS_ID + " ;" 2004a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + " END"); 2005603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2006603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 2007d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private void createGrantsTable(SQLiteDatabase db) { 2008d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana db.execSQL("CREATE TABLE " + TABLE_GRANTS + " ( " 2009d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + GRANTS_ACCOUNTS_ID + " INTEGER NOT NULL, " 2010d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + GRANTS_AUTH_TOKEN_TYPE + " STRING NOT NULL, " 2011d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + GRANTS_GRANTEE_UID + " INTEGER NOT NULL, " 2012d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + "UNIQUE (" + GRANTS_ACCOUNTS_ID + "," + GRANTS_AUTH_TOKEN_TYPE 2013d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + "," + GRANTS_GRANTEE_UID + "))"); 2014d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2015d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 2016603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana @Override 2017603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 2018a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana Log.e(TAG, "upgrade from version " + oldVersion + " to version " + newVersion); 2019603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 2020a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (oldVersion == 1) { 2021d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana // no longer need to do anything since the work is done 2022d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana // when upgrading from version 2 2023d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana oldVersion++; 2024d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2025d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 2026d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (oldVersion == 2) { 2027d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana createGrantsTable(db); 2028d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana db.execSQL("DROP TRIGGER " + TABLE_ACCOUNTS + "Delete"); 2029d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana createAccountsDeletionTrigger(db); 2030a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana oldVersion++; 2031a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 20323348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache 20333348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache if (oldVersion == 3) { 20343348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache db.execSQL("UPDATE " + TABLE_ACCOUNTS + " SET " + ACCOUNTS_TYPE + 20353348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache " = 'com.google' WHERE " + ACCOUNTS_TYPE + " == 'com.google.GAIA'"); 20363348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache oldVersion++; 20373348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache } 2038603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2039603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 2040603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana @Override 2041603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public void onOpen(SQLiteDatabase db) { 2042603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "opened database " + DATABASE_NAME); 2043603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2044603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2045603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 2046603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public IBinder onBind(Intent intent) { 2047603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana return asBinder(); 2048603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2049a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 20501cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks /** 20511cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks * Searches array of arguments for the specified string 20521cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks * @param args array of argument strings 20531cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks * @param value value to search for 20541cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks * @return true if the value is contained in the array 20551cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks */ 20561cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks private static boolean scanArgs(String[] args, String value) { 20571cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks if (args != null) { 20581cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks for (String arg : args) { 20591cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks if (value.equals(arg)) { 20601cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks return true; 20611cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks } 2062a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 2063a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 20641cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks return false; 20651cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks } 2066a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 20676eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey @Override 20681cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) { 20693abd75ba3a981850cac43a401d0014a836559cb0Kenny Root if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 20703abd75ba3a981850cac43a401d0014a836559cb0Kenny Root != PackageManager.PERMISSION_GRANTED) { 20713abd75ba3a981850cac43a401d0014a836559cb0Kenny Root fout.println("Permission Denial: can't dump AccountsManager from from pid=" 20723abd75ba3a981850cac43a401d0014a836559cb0Kenny Root + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 20733abd75ba3a981850cac43a401d0014a836559cb0Kenny Root + " without permission " + android.Manifest.permission.DUMP); 20743abd75ba3a981850cac43a401d0014a836559cb0Kenny Root return; 20753abd75ba3a981850cac43a401d0014a836559cb0Kenny Root } 207604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final boolean isCheckinRequest = scanArgs(args, "--checkin") || scanArgs(args, "-c"); 20776eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey final IndentingPrintWriter ipw = new IndentingPrintWriter(fout, " "); 20786eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey 20796eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey final List<UserInfo> users = getUserManager().getUsers(); 20806eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey for (UserInfo user : users) { 20816eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey ipw.println("User " + user + ":"); 20826eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey ipw.increaseIndent(); 20836eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey dumpUser(getUserAccounts(user.id), fd, ipw, args, isCheckinRequest); 20846eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey ipw.println(); 20856eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey ipw.decreaseIndent(); 208604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 208704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 20881cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks 208904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private void dumpUser(UserAccounts userAccounts, FileDescriptor fd, PrintWriter fout, 209004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani String[] args, boolean isCheckinRequest) { 209104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (userAccounts.cacheLock) { 209204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = userAccounts.openHelper.getReadableDatabase(); 2093a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 2094f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (isCheckinRequest) { 2095f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana // This is a checkin request. *Only* upload the account types and the count of each. 2096f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana Cursor cursor = db.query(TABLE_ACCOUNTS, ACCOUNT_TYPE_COUNT_PROJECTION, 2097f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana null, null, ACCOUNTS_TYPE, null, null); 2098f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana try { 2099f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana while (cursor.moveToNext()) { 2100f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana // print type,count 2101f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana fout.println(cursor.getString(0) + "," + cursor.getString(1)); 2102f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 2103f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } finally { 2104f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (cursor != null) { 2105f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana cursor.close(); 2106f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 21071cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks } 2108f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } else { 210904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani Account[] accounts = getAccountsFromCacheLocked(userAccounts, null /* type */); 2110f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana fout.println("Accounts: " + accounts.length); 2111f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana for (Account account : accounts) { 2112f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana fout.println(" " + account); 21131cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks } 2114307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana 2115f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana fout.println(); 2116f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana synchronized (mSessions) { 2117f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana final long now = SystemClock.elapsedRealtime(); 2118f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana fout.println("Active Sessions: " + mSessions.size()); 2119f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana for (Session session : mSessions.values()) { 2120f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana fout.println(" " + session.toDebugString(now)); 2121f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 21221cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks } 21231cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks 2124f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana fout.println(); 21256ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey mAuthenticatorCache.dump(fd, fout, args, userAccounts.userId); 2126f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 21271cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks } 2128a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 2129a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 213004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private void doNotification(UserAccounts accounts, Account account, CharSequence message, 21314120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn Intent intent, int userId) { 213226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 213326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 213426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 213526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana Log.v(TAG, "doNotification: " + message + " intent:" + intent); 213626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 2137a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 2138d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (intent.getComponent() != null && 2139d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana GrantCredentialsPermissionActivity.class.getName().equals( 2140d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana intent.getComponent().getClassName())) { 21414120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn createNoCredentialsPermissionNotification(account, intent, userId); 2142d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } else { 214304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final Integer notificationId = getSigninRequiredNotificationId(accounts, account); 214433f889ae270f888f8fdc084f5f1f3d443532a46aFred Quintana intent.addCategory(String.valueOf(notificationId)); 2145d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Notification n = new Notification(android.R.drawable.stat_sys_warning, null, 2146d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 0 /* when */); 214750cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn UserHandle user = new UserHandle(userId); 214833f889ae270f888f8fdc084f5f1f3d443532a46aFred Quintana final String notificationTitleFormat = 214933f889ae270f888f8fdc084f5f1f3d443532a46aFred Quintana mContext.getText(R.string.notification_title).toString(); 215033f889ae270f888f8fdc084f5f1f3d443532a46aFred Quintana n.setLatestEventInfo(mContext, 215133f889ae270f888f8fdc084f5f1f3d443532a46aFred Quintana String.format(notificationTitleFormat, account.name), 21524120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn message, PendingIntent.getActivityAsUser( 21534120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn mContext, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT, 215450cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn null, user)); 215550cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn installNotification(notificationId, n, user); 2156d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 215726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 215826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 215926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 2160a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 2161a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 216250cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn protected void installNotification(final int notificationId, final Notification n, 216350cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn UserHandle user) { 216456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana ((NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE)) 216550cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn .notifyAsUser(null, notificationId, n, user); 216656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 216756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 216850cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn protected void cancelNotification(int id, UserHandle user) { 216926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 217026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 217126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana ((NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE)) 217250cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn .cancelAsUser(null, id, user); 217326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 217426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 217526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 2176a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 2177d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 2178b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana /** Succeeds if any of the specified permissions are granted. */ 2179b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana private void checkBinderPermission(String... permissions) { 2180d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana final int uid = Binder.getCallingUid(); 2181b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana 2182b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana for (String perm : permissions) { 2183b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana if (mContext.checkCallingOrSelfPermission(perm) == PackageManager.PERMISSION_GRANTED) { 2184b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 218556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, " caller uid " + uid + " has " + perm); 2186b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana } 2187b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana return; 2188b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana } 2189d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2190b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana 2191b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana String msg = "caller uid " + uid + " lacks any of " + TextUtils.join(",", permissions); 219256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.w(TAG, " " + msg); 2193b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana throw new SecurityException(msg); 2194d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2195d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 21966ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey private boolean inSystemImage(int callingUid) { 21976ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey final int callingUserId = UserHandle.getUserId(callingUid); 21986ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey 21996ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey final PackageManager userPackageManager; 22006ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey try { 22016ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey userPackageManager = mContext.createPackageContextAsUser( 22026ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey "android", 0, new UserHandle(callingUserId)).getPackageManager(); 22036ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey } catch (NameNotFoundException e) { 22046ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey return false; 22056ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey } 22066ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey 22076ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey String[] packages = userPackageManager.getPackagesForUid(callingUid); 22087be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana for (String name : packages) { 22097be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana try { 22106ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey PackageInfo packageInfo = userPackageManager.getPackageInfo(name, 0 /* flags */); 221156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (packageInfo != null 221256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana && (packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 22137be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana return true; 22147be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana } 22157be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana } catch (PackageManager.NameNotFoundException e) { 22167be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana return false; 22177be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana } 22187be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana } 22197be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana return false; 22207be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana } 22217be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana 2222d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private boolean permissionIsGranted(Account account, String authTokenType, int callerUid) { 2223b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana final boolean inSystemImage = inSystemImage(callerUid); 222431957f1badbb900bbfe211317e1ea992d650a72dFred Quintana final boolean fromAuthenticator = account != null 222531957f1badbb900bbfe211317e1ea992d650a72dFred Quintana && hasAuthenticatorUid(account.type, callerUid); 222631957f1badbb900bbfe211317e1ea992d650a72dFred Quintana final boolean hasExplicitGrants = account != null 222704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani && hasExplicitlyGrantedPermission(account, authTokenType, callerUid); 2228d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 2229d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Log.v(TAG, "checkGrantsOrCallingUidAgainstAuthenticator: caller uid " 223056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + callerUid + ", " + account 2231d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + ": is authenticator? " + fromAuthenticator 2232d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + ", has explicit permission? " + hasExplicitGrants); 2233d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2234b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana return fromAuthenticator || hasExplicitGrants || inSystemImage; 2235d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2236d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 22371a23191bbde11505d6e0c25c04a60b41cb27fd31Fred Quintana private boolean hasAuthenticatorUid(String accountType, int callingUid) { 22386ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey final int callingUserId = UserHandle.getUserId(callingUid); 2239d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana for (RegisteredServicesCache.ServiceInfo<AuthenticatorDescription> serviceInfo : 22406ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey mAuthenticatorCache.getAllServices(callingUserId)) { 2241d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (serviceInfo.type.type.equals(accountType)) { 2242ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana return (serviceInfo.uid == callingUid) || 224356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana (mPackageManager.checkSignatures(serviceInfo.uid, callingUid) 2244ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana == PackageManager.SIGNATURE_MATCH); 2245d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2246d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2247d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana return false; 2248d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2249d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 225004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private boolean hasExplicitlyGrantedPermission(Account account, String authTokenType, 225104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani int callerUid) { 225204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani if (callerUid == android.os.Process.SYSTEM_UID) { 2253d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana return true; 2254d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 225504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 225604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 225704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getReadableDatabase(); 225804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani String[] args = { String.valueOf(callerUid), authTokenType, 2259f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana account.name, account.type}; 2260f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana final boolean permissionGranted = 2261f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana DatabaseUtils.longForQuery(db, COUNT_OF_MATCHING_GRANTS, args) != 0; 2262f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (!permissionGranted && ActivityManager.isRunningInTestHarness()) { 2263f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana // TODO: Skip this check when running automated tests. Replace this 2264f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana // with a more general solution. 2265f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana Log.d(TAG, "no credentials permission for usage of " + account + ", " 226604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani + authTokenType + " by uid " + callerUid 2267f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana + " but ignoring since device is in test harness."); 2268f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return true; 2269f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 2270f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return permissionGranted; 2271d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2272d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2273d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 2274d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private void checkCallingUidAgainstAuthenticator(Account account) { 2275d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana final int uid = Binder.getCallingUid(); 227631957f1badbb900bbfe211317e1ea992d650a72dFred Quintana if (account == null || !hasAuthenticatorUid(account.type, uid)) { 2277d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana String msg = "caller uid " + uid + " is different than the authenticator's uid"; 2278d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Log.w(TAG, msg); 2279d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana throw new SecurityException(msg); 2280d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2281d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 2282d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Log.v(TAG, "caller uid " + uid + " is the same as the authenticator's uid"); 2283d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2284d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2285d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 2286d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private void checkAuthenticateAccountsPermission(Account account) { 2287d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkBinderPermission(Manifest.permission.AUTHENTICATE_ACCOUNTS); 2288d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkCallingUidAgainstAuthenticator(account); 2289d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2290d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 2291d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private void checkReadAccountsPermission() { 2292d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkBinderPermission(Manifest.permission.GET_ACCOUNTS); 2293d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2294d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 2295d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private void checkManageAccountsPermission() { 2296d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkBinderPermission(Manifest.permission.MANAGE_ACCOUNTS); 2297d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2298d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 2299b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana private void checkManageAccountsOrUseCredentialsPermissions() { 2300b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana checkBinderPermission(Manifest.permission.MANAGE_ACCOUNTS, 2301b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana Manifest.permission.USE_CREDENTIALS); 2302b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana } 2303b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana 2304d9640ec712806508877868d08aafaa2d715ff441Fred Quintana public void updateAppPermission(Account account, String authTokenType, int uid, boolean value) 2305d9640ec712806508877868d08aafaa2d715ff441Fred Quintana throws RemoteException { 2306d9640ec712806508877868d08aafaa2d715ff441Fred Quintana final int callingUid = getCallingUid(); 2307d9640ec712806508877868d08aafaa2d715ff441Fred Quintana 2308d9640ec712806508877868d08aafaa2d715ff441Fred Quintana if (callingUid != android.os.Process.SYSTEM_UID) { 2309d9640ec712806508877868d08aafaa2d715ff441Fred Quintana throw new SecurityException(); 2310d9640ec712806508877868d08aafaa2d715ff441Fred Quintana } 2311d9640ec712806508877868d08aafaa2d715ff441Fred Quintana 2312d9640ec712806508877868d08aafaa2d715ff441Fred Quintana if (value) { 2313d9640ec712806508877868d08aafaa2d715ff441Fred Quintana grantAppPermission(account, authTokenType, uid); 2314d9640ec712806508877868d08aafaa2d715ff441Fred Quintana } else { 2315d9640ec712806508877868d08aafaa2d715ff441Fred Quintana revokeAppPermission(account, authTokenType, uid); 2316d9640ec712806508877868d08aafaa2d715ff441Fred Quintana } 2317d9640ec712806508877868d08aafaa2d715ff441Fred Quintana } 2318d9640ec712806508877868d08aafaa2d715ff441Fred Quintana 2319d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana /** 2320d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * Allow callers with the given uid permission to get credentials for account/authTokenType. 2321d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * <p> 2322d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * Although this is public it can only be accessed via the AccountManagerService object 2323d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * which is in the system. This means we don't need to protect it with permissions. 2324d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * @hide 2325d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana */ 2326d9640ec712806508877868d08aafaa2d715ff441Fred Quintana private void grantAppPermission(Account account, String authTokenType, int uid) { 2327382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null || authTokenType == null) { 2328382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana Log.e(TAG, "grantAppPermission: called with invalid arguments", new Exception()); 232931957f1badbb900bbfe211317e1ea992d650a72dFred Quintana return; 233031957f1badbb900bbfe211317e1ea992d650a72dFred Quintana } 2331f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackborn UserAccounts accounts = getUserAccounts(UserHandle.getUserId(uid)); 233204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 233304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getWritableDatabase(); 2334f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.beginTransaction(); 2335f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana try { 2336f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana long accountId = getAccountIdLocked(db, account); 2337f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (accountId >= 0) { 2338f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana ContentValues values = new ContentValues(); 2339f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana values.put(GRANTS_ACCOUNTS_ID, accountId); 2340f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana values.put(GRANTS_AUTH_TOKEN_TYPE, authTokenType); 2341f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana values.put(GRANTS_GRANTEE_UID, uid); 2342f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.insert(TABLE_GRANTS, GRANTS_ACCOUNTS_ID, values); 2343f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.setTransactionSuccessful(); 2344f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 2345f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } finally { 2346f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.endTransaction(); 2347d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 234850cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn cancelNotification(getCredentialPermissionNotificationId(account, authTokenType, uid), 234950cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn new UserHandle(accounts.userId)); 2350d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2351d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2352d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 2353d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana /** 2354d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * Don't allow callers with the given uid permission to get credentials for 2355d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * account/authTokenType. 2356d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * <p> 2357d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * Although this is public it can only be accessed via the AccountManagerService object 2358d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * which is in the system. This means we don't need to protect it with permissions. 2359d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * @hide 2360d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana */ 2361d9640ec712806508877868d08aafaa2d715ff441Fred Quintana private void revokeAppPermission(Account account, String authTokenType, int uid) { 2362382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null || authTokenType == null) { 2363382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana Log.e(TAG, "revokeAppPermission: called with invalid arguments", new Exception()); 236431957f1badbb900bbfe211317e1ea992d650a72dFred Quintana return; 236531957f1badbb900bbfe211317e1ea992d650a72dFred Quintana } 2366f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackborn UserAccounts accounts = getUserAccounts(UserHandle.getUserId(uid)); 236704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 236804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getWritableDatabase(); 2369f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.beginTransaction(); 2370f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana try { 2371f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana long accountId = getAccountIdLocked(db, account); 2372f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (accountId >= 0) { 2373f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.delete(TABLE_GRANTS, 2374f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana GRANTS_ACCOUNTS_ID + "=? AND " + GRANTS_AUTH_TOKEN_TYPE + "=? AND " 2375f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana + GRANTS_GRANTEE_UID + "=?", 2376f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana new String[]{String.valueOf(accountId), authTokenType, 2377f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana String.valueOf(uid)}); 2378f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.setTransactionSuccessful(); 2379f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 2380f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } finally { 2381f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.endTransaction(); 2382d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 238350cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn cancelNotification(getCredentialPermissionNotificationId(account, authTokenType, uid), 238450cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn new UserHandle(accounts.userId)); 2385d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2386d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 238756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 238856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana static final private String stringArrayToString(String[] value) { 238956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana return value != null ? ("[" + TextUtils.join(",", value) + "]") : null; 239056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 239156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 239204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private void removeAccountFromCacheLocked(UserAccounts accounts, Account account) { 239304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final Account[] oldAccountsForType = accounts.accountCache.get(account.type); 2394f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (oldAccountsForType != null) { 2395f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana ArrayList<Account> newAccountsList = new ArrayList<Account>(); 2396f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana for (Account curAccount : oldAccountsForType) { 2397f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (!curAccount.equals(account)) { 2398f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana newAccountsList.add(curAccount); 239956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 240056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 2401f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (newAccountsList.isEmpty()) { 240204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.accountCache.remove(account.type); 2403f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } else { 2404f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana Account[] newAccountsForType = new Account[newAccountsList.size()]; 2405f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana newAccountsForType = newAccountsList.toArray(newAccountsForType); 240604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.accountCache.put(account.type, newAccountsForType); 2407f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 240856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 240904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.userDataCache.remove(account); 241004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.authTokenCache.remove(account); 241156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 241256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 241356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana /** 241456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana * This assumes that the caller has already checked that the account is not already present. 241556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana */ 241604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private void insertAccountIntoCacheLocked(UserAccounts accounts, Account account) { 241704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani Account[] accountsForType = accounts.accountCache.get(account.type); 2418f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana int oldLength = (accountsForType != null) ? accountsForType.length : 0; 2419f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana Account[] newAccountsForType = new Account[oldLength + 1]; 2420f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (accountsForType != null) { 2421f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana System.arraycopy(accountsForType, 0, newAccountsForType, 0, oldLength); 2422f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 2423f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana newAccountsForType[oldLength] = account; 242404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.accountCache.put(account.type, newAccountsForType); 2425f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 2426f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana 242704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani protected Account[] getAccountsFromCacheLocked(UserAccounts userAccounts, String accountType) { 2428f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (accountType != null) { 242904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final Account[] accounts = userAccounts.accountCache.get(accountType); 2430f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (accounts == null) { 2431f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return EMPTY_ACCOUNT_ARRAY; 243256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } else { 2433f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return Arrays.copyOf(accounts, accounts.length); 2434f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 2435f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } else { 2436f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana int totalLength = 0; 243704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani for (Account[] accounts : userAccounts.accountCache.values()) { 2438f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana totalLength += accounts.length; 2439f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 2440f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (totalLength == 0) { 2441f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return EMPTY_ACCOUNT_ARRAY; 2442f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 2443f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana Account[] accounts = new Account[totalLength]; 2444f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana totalLength = 0; 244504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani for (Account[] accountsOfType : userAccounts.accountCache.values()) { 2446f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana System.arraycopy(accountsOfType, 0, accounts, totalLength, 2447f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana accountsOfType.length); 2448f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana totalLength += accountsOfType.length; 244956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 2450f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return accounts; 245156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 245256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 245356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 245404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani protected void writeUserDataIntoCacheLocked(UserAccounts accounts, final SQLiteDatabase db, 245504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani Account account, String key, String value) { 245604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani HashMap<String, String> userDataForAccount = accounts.userDataCache.get(account); 2457f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (userDataForAccount == null) { 2458f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana userDataForAccount = readUserDataForAccountFromDatabaseLocked(db, account); 245904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.userDataCache.put(account, userDataForAccount); 2460f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 2461f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (value == null) { 2462f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana userDataForAccount.remove(key); 2463f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } else { 2464f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana userDataForAccount.put(key, value); 246556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 246656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 246756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 246804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani protected void writeAuthTokenIntoCacheLocked(UserAccounts accounts, final SQLiteDatabase db, 246904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani Account account, String key, String value) { 247004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani HashMap<String, String> authTokensForAccount = accounts.authTokenCache.get(account); 2471f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (authTokensForAccount == null) { 2472f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana authTokensForAccount = readAuthTokensForAccountFromDatabaseLocked(db, account); 247304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.authTokenCache.put(account, authTokensForAccount); 2474f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 2475f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (value == null) { 2476f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana authTokensForAccount.remove(key); 2477f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } else { 2478f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana authTokensForAccount.put(key, value); 247956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 248056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 248156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 248204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani protected String readAuthTokenInternal(UserAccounts accounts, Account account, 248304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani String authTokenType) { 248404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 248504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani HashMap<String, String> authTokensForAccount = accounts.authTokenCache.get(account); 248656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (authTokensForAccount == null) { 248756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana // need to populate the cache for this account 248804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getReadableDatabase(); 2489f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana authTokensForAccount = readAuthTokensForAccountFromDatabaseLocked(db, account); 249004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.authTokenCache.put(account, authTokensForAccount); 249156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 249256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana return authTokensForAccount.get(authTokenType); 249356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 249456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 249556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 249604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani protected String readUserDataInternal(UserAccounts accounts, Account account, String key) { 249704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 249804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani HashMap<String, String> userDataForAccount = accounts.userDataCache.get(account); 249956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (userDataForAccount == null) { 250056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana // need to populate the cache for this account 250104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getReadableDatabase(); 2502f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana userDataForAccount = readUserDataForAccountFromDatabaseLocked(db, account); 250304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.userDataCache.put(account, userDataForAccount); 250456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 250556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana return userDataForAccount.get(key); 250656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 250756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 250856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 2509f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana protected HashMap<String, String> readUserDataForAccountFromDatabaseLocked( 2510f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana final SQLiteDatabase db, Account account) { 251156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana HashMap<String, String> userDataForAccount = new HashMap<String, String>(); 251256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Cursor cursor = db.query(TABLE_EXTRAS, 251356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana COLUMNS_EXTRAS_KEY_AND_VALUE, 251456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana SELECTION_USERDATA_BY_ACCOUNT, 251556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana new String[]{account.name, account.type}, 251656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana null, null, null); 251756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana try { 251856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana while (cursor.moveToNext()) { 251956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final String tmpkey = cursor.getString(0); 252056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final String value = cursor.getString(1); 252156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana userDataForAccount.put(tmpkey, value); 252256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 252356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } finally { 252456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana cursor.close(); 252556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 252656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana return userDataForAccount; 252756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 252856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 2529f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana protected HashMap<String, String> readAuthTokensForAccountFromDatabaseLocked( 2530f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana final SQLiteDatabase db, Account account) { 253156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana HashMap<String, String> authTokensForAccount = new HashMap<String, String>(); 253256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Cursor cursor = db.query(TABLE_AUTHTOKENS, 253356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana COLUMNS_AUTHTOKENS_TYPE_AND_AUTHTOKEN, 253456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana SELECTION_AUTHTOKENS_BY_ACCOUNT, 253556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana new String[]{account.name, account.type}, 253656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana null, null, null); 253756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana try { 253856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana while (cursor.moveToNext()) { 253956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final String type = cursor.getString(0); 254056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final String authToken = cursor.getString(1); 254156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana authTokensForAccount.put(type, authToken); 254256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 254356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } finally { 254456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana cursor.close(); 254556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 254656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana return authTokensForAccount; 254756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 2548603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana} 2549