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 177a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkeypackage com.android.server.accounts; 18603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 19885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongkerimport android.Manifest; 207a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkeyimport android.accounts.Account; 217a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkeyimport android.accounts.AccountAndUser; 227a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkeyimport android.accounts.AccountAuthenticatorResponse; 237a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkeyimport android.accounts.AccountManager; 247a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkeyimport android.accounts.AuthenticatorDescription; 2523c8b96a7e5c3f4c169bf65ae3886357943bb7b0Amith Yamasaniimport android.accounts.CantAddAccountActivity; 267a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkeyimport android.accounts.GrantCredentialsPermissionActivity; 277a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkeyimport android.accounts.IAccountAuthenticator; 287a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkeyimport android.accounts.IAccountAuthenticatorResponse; 297a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkeyimport android.accounts.IAccountManager; 307a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkeyimport android.accounts.IAccountManagerResponse; 313b4fcbc9f13bab6a2e9e5c37cc5e18fec7341c04Brett Chabotimport android.app.ActivityManager; 326ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkeyimport android.app.ActivityManagerNative; 333b458ad9ee5f2d6b7cf28a13bc29123cdf540763Amith Yamasaniimport android.app.AppGlobals; 34885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongkerimport android.app.Notification; 35885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongkerimport android.app.NotificationManager; 36885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongkerimport android.app.PendingIntent; 37a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.content.BroadcastReceiver; 38885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongkerimport android.content.ComponentName; 39a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.content.ContentValues; 40a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.content.Context; 41a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.content.Intent; 42a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.content.IntentFilter; 43b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintanaimport android.content.ServiceConnection; 44885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongkerimport android.content.pm.ApplicationInfo; 45885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongkerimport android.content.pm.PackageInfo; 46d4a1d2e14297a3387fdb5761090961e714370492Fred Quintanaimport android.content.pm.PackageManager; 476ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkeyimport android.content.pm.PackageManager.NameNotFoundException; 48d4a1d2e14297a3387fdb5761090961e714370492Fred Quintanaimport android.content.pm.RegisteredServicesCache; 493ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintanaimport android.content.pm.RegisteredServicesCacheListener; 505bab9daf3cf66f4de19f8757e386030e8bef23ceCarlos Valdiviaimport android.content.pm.ResolveInfo; 516eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkeyimport android.content.pm.UserInfo; 52603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintanaimport android.database.Cursor; 53603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintanaimport android.database.DatabaseUtils; 54a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.database.sqlite.SQLiteDatabase; 55a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.database.sqlite.SQLiteOpenHelper; 56885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongkerimport android.os.Binder; 57a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.os.Bundle; 58a8529f68671a8a118751cb6ad577f44eaf076b96Oscar Montemayorimport android.os.Environment; 59a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.os.Handler; 60a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.os.IBinder; 61a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.os.Looper; 62a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.os.Message; 63164371fb759bad6854570af0fca60d9a01e17235Dianne Hackbornimport android.os.Parcel; 6427db46850b708070452c0ce49daf5f79503fbde6Amith Yamasaniimport android.os.Process; 65a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.os.RemoteException; 66a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.os.SystemClock; 67f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackbornimport android.os.UserHandle; 68258848d2ae04f447ff1c18023fa76b139fcc0862Amith Yamasaniimport android.os.UserManager; 69a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.text.TextUtils; 70a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.util.Log; 71d4a1d2e14297a3387fdb5761090961e714370492Fred Quintanaimport android.util.Pair; 726eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkeyimport android.util.Slog; 7304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasaniimport android.util.SparseArray; 74603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 75b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolacheimport com.android.internal.R; 7667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasaniimport com.android.internal.util.ArrayUtils; 7704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasaniimport com.android.internal.util.IndentingPrintWriter; 788d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackbornimport com.android.server.FgThread; 796ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkeyimport com.google.android.collect.Lists; 806ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkeyimport com.google.android.collect.Sets; 81b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache 82a8529f68671a8a118751cb6ad577f44eaf076b96Oscar Montemayorimport java.io.File; 83a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport java.io.FileDescriptor; 84a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport java.io.PrintWriter; 85a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport java.util.ArrayList; 8656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintanaimport java.util.Arrays; 87a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport java.util.Collection; 88d4a1d2e14297a3387fdb5761090961e714370492Fred Quintanaimport java.util.HashMap; 896ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkeyimport java.util.HashSet; 9056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintanaimport java.util.LinkedHashMap; 916eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkeyimport java.util.List; 922f36229db823d152f3efd879e751e81a601a75b0Andy McFaddenimport java.util.Map; 93d4a1d2e14297a3387fdb5761090961e714370492Fred Quintanaimport java.util.concurrent.atomic.AtomicInteger; 94d4a1d2e14297a3387fdb5761090961e714370492Fred Quintanaimport java.util.concurrent.atomic.AtomicReference; 95603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 96603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana/** 97603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * A system service that provides account, password, and authtoken management for all 98603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * accounts on the device. Some of these calls are implemented with the help of the corresponding 99603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * {@link IAccountAuthenticator} services. This service is not accessed by users directly, 100603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * instead one uses an instance of {@link AccountManager}, which can be accessed as follows: 10146703b099516c383a6882815bcf9cd4df0ec538dBrian Carlstrom * AccountManager accountManager = AccountManager.get(context); 1023326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana * @hide 103603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana */ 1043ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintanapublic class AccountManagerService 1053ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintana extends IAccountManager.Stub 1065ebbb4a6b3e16f711735ae0615b9a9ea64faad38Fred Quintana implements RegisteredServicesCacheListener<AuthenticatorDescription> { 107603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String TAG = "AccountManagerService"; 108603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 109603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final int TIMEOUT_DELAY_MS = 1000 * 60; 110603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String DATABASE_NAME = "accounts.db"; 11167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani private static final int DATABASE_VERSION = 5; 112603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 113603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private final Context mContext; 114603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 11556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana private final PackageManager mPackageManager; 116258848d2ae04f447ff1c18023fa76b139fcc0862Amith Yamasani private UserManager mUserManager; 11756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 118603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private final MessageHandler mMessageHandler; 119603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 120603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana // Messages that can be sent on mHandler 121603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final int MESSAGE_TIMED_OUT = 3; 1225be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani private static final int MESSAGE_COPY_SHARED_ACCOUNT = 4; 123603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 12456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana private final IAccountAuthenticatorCache mAuthenticatorCache; 125603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 126603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String TABLE_ACCOUNTS = "accounts"; 127603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String ACCOUNTS_ID = "_id"; 128603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String ACCOUNTS_NAME = "name"; 129603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String ACCOUNTS_TYPE = "type"; 1301cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks private static final String ACCOUNTS_TYPE_COUNT = "count(type)"; 131603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String ACCOUNTS_PASSWORD = "password"; 132603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 133603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String TABLE_AUTHTOKENS = "authtokens"; 134603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String AUTHTOKENS_ID = "_id"; 135603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String AUTHTOKENS_ACCOUNTS_ID = "accounts_id"; 136603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String AUTHTOKENS_TYPE = "type"; 137603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String AUTHTOKENS_AUTHTOKEN = "authtoken"; 138603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 139d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private static final String TABLE_GRANTS = "grants"; 140d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private static final String GRANTS_ACCOUNTS_ID = "accounts_id"; 141d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private static final String GRANTS_AUTH_TOKEN_TYPE = "auth_token_type"; 142d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private static final String GRANTS_GRANTEE_UID = "uid"; 143d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 144603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String TABLE_EXTRAS = "extras"; 145603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String EXTRAS_ID = "_id"; 146603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String EXTRAS_ACCOUNTS_ID = "accounts_id"; 147603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String EXTRAS_KEY = "key"; 148603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String EXTRAS_VALUE = "value"; 149603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 150603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String TABLE_META = "meta"; 151603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String META_KEY = "key"; 152603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String META_VALUE = "value"; 153603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 15467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani private static final String TABLE_SHARED_ACCOUNTS = "shared_accounts"; 15567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani 1561cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks private static final String[] ACCOUNT_TYPE_COUNT_PROJECTION = 1571cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks new String[] { ACCOUNTS_TYPE, ACCOUNTS_TYPE_COUNT}; 1587be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana private static final Intent ACCOUNTS_CHANGED_INTENT; 159a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 160d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private static final String COUNT_OF_MATCHING_GRANTS = "" 161d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + "SELECT COUNT(*) FROM " + TABLE_GRANTS + ", " + TABLE_ACCOUNTS 162d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + " WHERE " + GRANTS_ACCOUNTS_ID + "=" + ACCOUNTS_ID 163d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + " AND " + GRANTS_GRANTEE_UID + "=?" 164d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + " AND " + GRANTS_AUTH_TOKEN_TYPE + "=?" 165d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + " AND " + ACCOUNTS_NAME + "=?" 166d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + " AND " + ACCOUNTS_TYPE + "=?"; 167d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 16856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana private static final String SELECTION_AUTHTOKENS_BY_ACCOUNT = 16956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana AUTHTOKENS_ACCOUNTS_ID + "=(select _id FROM accounts WHERE name=? AND type=?)"; 17056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana private static final String[] COLUMNS_AUTHTOKENS_TYPE_AND_AUTHTOKEN = {AUTHTOKENS_TYPE, 17156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana AUTHTOKENS_AUTHTOKEN}; 17256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 17356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana private static final String SELECTION_USERDATA_BY_ACCOUNT = 17456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana EXTRAS_ACCOUNTS_ID + "=(select _id FROM accounts WHERE name=? AND type=?)"; 17556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana private static final String[] COLUMNS_EXTRAS_KEY_AND_VALUE = {EXTRAS_KEY, EXTRAS_VALUE}; 17656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 177a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana private final LinkedHashMap<String, Session> mSessions = new LinkedHashMap<String, Session>(); 178d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private final AtomicInteger mNotificationIds = new AtomicInteger(1); 179d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 18004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani static class UserAccounts { 18104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private final int userId; 18204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private final DatabaseHelper openHelper; 18304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private final HashMap<Pair<Pair<Account, String>, Integer>, Integer> 18404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani credentialsPermissionNotificationIds = 18504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani new HashMap<Pair<Pair<Account, String>, Integer>, Integer>(); 18604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private final HashMap<Account, Integer> signinRequiredNotificationIds = 18704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani new HashMap<Account, Integer>(); 18804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private final Object cacheLock = new Object(); 18904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani /** protected by the {@link #cacheLock} */ 190b483a99c6bdfee72fbb8fbcf893e63ef3f54658bAmith Yamasani private final HashMap<String, Account[]> accountCache = 191b483a99c6bdfee72fbb8fbcf893e63ef3f54658bAmith Yamasani new LinkedHashMap<String, Account[]>(); 19204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani /** protected by the {@link #cacheLock} */ 19309e7e0ef8bcd8b7b78b79fb570de2032871f0c97Jatin Lodhia private final HashMap<Account, HashMap<String, String>> userDataCache = 19404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani new HashMap<Account, HashMap<String, String>>(); 19504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani /** protected by the {@link #cacheLock} */ 19609e7e0ef8bcd8b7b78b79fb570de2032871f0c97Jatin Lodhia private final HashMap<Account, HashMap<String, String>> authTokenCache = 19704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani new HashMap<Account, HashMap<String, String>>(); 19804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani 19904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts(Context context, int userId) { 20004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani this.userId = userId; 20104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (cacheLock) { 20204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani openHelper = new DatabaseHelper(context, userId); 20304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 20404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 20504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 20604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani 20704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private final SparseArray<UserAccounts> mUsers = new SparseArray<UserAccounts>(); 20804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani 209d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private static AtomicReference<AccountManagerService> sThis = 210d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana new AtomicReference<AccountManagerService>(); 21131957f1badbb900bbfe211317e1ea992d650a72dFred Quintana private static final Account[] EMPTY_ACCOUNT_ARRAY = new Account[]{}; 2127be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana 2137be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana static { 214f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana ACCOUNTS_CHANGED_INTENT = new Intent(AccountManager.LOGIN_ACCOUNTS_CHANGED_ACTION); 2157be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana ACCOUNTS_CHANGED_INTENT.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 2167be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana } 2177be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana 21856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 219d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana /** 220d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * This should only be called by system code. One should only call this after the service 221d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * has started. 222d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * @return a reference to the AccountManagerService instance 223d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * @hide 224d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana */ 225d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana public static AccountManagerService getSingleton() { 226d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana return sThis.get(); 227d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 228603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 22956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana public AccountManagerService(Context context) { 23056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana this(context, context.getPackageManager(), new AccountAuthenticatorCache(context)); 231603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 232603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 23356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana public AccountManagerService(Context context, PackageManager packageManager, 23456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana IAccountAuthenticatorCache authenticatorCache) { 235603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mContext = context; 23656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana mPackageManager = packageManager; 237603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 2388d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn mMessageHandler = new MessageHandler(FgThread.get().getLooper()); 239603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 24056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana mAuthenticatorCache = authenticatorCache; 2415ebbb4a6b3e16f711735ae0615b9a9ea64faad38Fred Quintana mAuthenticatorCache.setListener(this, null /* Handler */); 242603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 243d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana sThis.set(this); 244afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana 245c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana IntentFilter intentFilter = new IntentFilter(); 246c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED); 247c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana intentFilter.addDataScheme("package"); 248c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana mContext.registerReceiver(new BroadcastReceiver() { 249c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana @Override 250c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana public void onReceive(Context context1, Intent intent) { 25104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani purgeOldGrantsAll(); 252c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana } 253c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana }, intentFilter); 254c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana 255135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani IntentFilter userFilter = new IntentFilter(); 256135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani userFilter.addAction(Intent.ACTION_USER_REMOVED); 25767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani userFilter.addAction(Intent.ACTION_USER_STARTED); 25867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani mContext.registerReceiverAsUser(new BroadcastReceiver() { 259135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani @Override 260135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani public void onReceive(Context context, Intent intent) { 26167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani String action = intent.getAction(); 26267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani if (Intent.ACTION_USER_REMOVED.equals(action)) { 26367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani onUserRemoved(intent); 26467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } else if (Intent.ACTION_USER_STARTED.equals(action)) { 26567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani onUserStarted(intent); 26667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 267135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani } 26867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani }, UserHandle.ALL, userFilter, null, null); 269afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana } 270afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana 271164371fb759bad6854570af0fca60d9a01e17235Dianne Hackborn @Override 272164371fb759bad6854570af0fca60d9a01e17235Dianne Hackborn public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 273164371fb759bad6854570af0fca60d9a01e17235Dianne Hackborn throws RemoteException { 274164371fb759bad6854570af0fca60d9a01e17235Dianne Hackborn try { 275164371fb759bad6854570af0fca60d9a01e17235Dianne Hackborn return super.onTransact(code, data, reply, flags); 276164371fb759bad6854570af0fca60d9a01e17235Dianne Hackborn } catch (RuntimeException e) { 277164371fb759bad6854570af0fca60d9a01e17235Dianne Hackborn // The account manager only throws security exceptions, so let's 278164371fb759bad6854570af0fca60d9a01e17235Dianne Hackborn // log all others. 279164371fb759bad6854570af0fca60d9a01e17235Dianne Hackborn if (!(e instanceof SecurityException)) { 280164371fb759bad6854570af0fca60d9a01e17235Dianne Hackborn Slog.wtf(TAG, "Account Manager Crash", e); 281164371fb759bad6854570af0fca60d9a01e17235Dianne Hackborn } 282164371fb759bad6854570af0fca60d9a01e17235Dianne Hackborn throw e; 283164371fb759bad6854570af0fca60d9a01e17235Dianne Hackborn } 284164371fb759bad6854570af0fca60d9a01e17235Dianne Hackborn } 285164371fb759bad6854570af0fca60d9a01e17235Dianne Hackborn 28626ff6626fc4ee0ae46f01ad309b366921da589feKenny Root public void systemReady() { 28726ff6626fc4ee0ae46f01ad309b366921da589feKenny Root } 28826ff6626fc4ee0ae46f01ad309b366921da589feKenny Root 289258848d2ae04f447ff1c18023fa76b139fcc0862Amith Yamasani private UserManager getUserManager() { 290258848d2ae04f447ff1c18023fa76b139fcc0862Amith Yamasani if (mUserManager == null) { 29127db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani mUserManager = UserManager.get(mContext); 292258848d2ae04f447ff1c18023fa76b139fcc0862Amith Yamasani } 293258848d2ae04f447ff1c18023fa76b139fcc0862Amith Yamasani return mUserManager; 294258848d2ae04f447ff1c18023fa76b139fcc0862Amith Yamasani } 295258848d2ae04f447ff1c18023fa76b139fcc0862Amith Yamasani 2960c19bf524493f2feedf442d390c878fd1ca66d7bAmith Yamasani /* Caller should lock mUsers */ 2970c19bf524493f2feedf442d390c878fd1ca66d7bAmith Yamasani private UserAccounts initUserLocked(int userId) { 2980c19bf524493f2feedf442d390c878fd1ca66d7bAmith Yamasani UserAccounts accounts = mUsers.get(userId); 2990c19bf524493f2feedf442d390c878fd1ca66d7bAmith Yamasani if (accounts == null) { 3000c19bf524493f2feedf442d390c878fd1ca66d7bAmith Yamasani accounts = new UserAccounts(mContext, userId); 3010c19bf524493f2feedf442d390c878fd1ca66d7bAmith Yamasani mUsers.append(userId, accounts); 3020c19bf524493f2feedf442d390c878fd1ca66d7bAmith Yamasani purgeOldGrants(accounts); 3030c19bf524493f2feedf442d390c878fd1ca66d7bAmith Yamasani validateAccountsInternal(accounts, true /* invalidateAuthenticatorCache */); 30404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 3050c19bf524493f2feedf442d390c878fd1ca66d7bAmith Yamasani return accounts; 30604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 30704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani 30804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private void purgeOldGrantsAll() { 30904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (mUsers) { 31004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani for (int i = 0; i < mUsers.size(); i++) { 31104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani purgeOldGrants(mUsers.valueAt(i)); 31204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 31304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 31404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 31504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani 31604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private void purgeOldGrants(UserAccounts accounts) { 31704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 31804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getWritableDatabase(); 319c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana final Cursor cursor = db.query(TABLE_GRANTS, 320c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana new String[]{GRANTS_GRANTEE_UID}, 321c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana null, null, GRANTS_GRANTEE_UID, null, null); 322c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana try { 323c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana while (cursor.moveToNext()) { 324c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana final int uid = cursor.getInt(0); 325c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana final boolean packageExists = mPackageManager.getPackagesForUid(uid) != null; 326c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana if (packageExists) { 327c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana continue; 328c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana } 329c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana Log.d(TAG, "deleting grants for UID " + uid 330c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana + " because its package is no longer installed"); 331c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana db.delete(TABLE_GRANTS, GRANTS_GRANTEE_UID + "=?", 332c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana new String[]{Integer.toString(uid)}); 333c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana } 334c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana } finally { 335c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana cursor.close(); 336c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana } 337c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana } 338c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana } 339c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana 3406eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey /** 3416eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey * Validate internal set of accounts against installed authenticators for 3426eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey * given user. Clears cached authenticators before validating. 3436eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey */ 3446eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey public void validateAccounts(int userId) { 3456eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey final UserAccounts accounts = getUserAccounts(userId); 3466eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey 3476eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey // Invalidate user-specific cache to make sure we catch any 3486eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey // removed authenticators. 3496eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey validateAccountsInternal(accounts, true /* invalidateAuthenticatorCache */); 3506eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey } 3516eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey 3526eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey /** 3536eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey * Validate internal set of accounts against installed authenticators for 3546eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey * given user. Clear cached authenticators before validating when requested. 3556eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey */ 3566eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey private void validateAccountsInternal( 3576eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey UserAccounts accounts, boolean invalidateAuthenticatorCache) { 3586eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey if (invalidateAuthenticatorCache) { 3596eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey mAuthenticatorCache.invalidateCache(accounts.userId); 3606eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey } 3616eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey 3626ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey final HashSet<AuthenticatorDescription> knownAuth = Sets.newHashSet(); 3636ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey for (RegisteredServicesCache.ServiceInfo<AuthenticatorDescription> service : 3646ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey mAuthenticatorCache.getAllServices(accounts.userId)) { 3656ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey knownAuth.add(service.type); 3666ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey } 3676ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey 36804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 36904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getWritableDatabase(); 370f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana boolean accountDeleted = false; 371f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana Cursor cursor = db.query(TABLE_ACCOUNTS, 372f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana new String[]{ACCOUNTS_ID, ACCOUNTS_TYPE, ACCOUNTS_NAME}, 373f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana null, null, null, null, null); 374f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana try { 37504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.accountCache.clear(); 37656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final HashMap<String, ArrayList<String>> accountNamesByType = 377b483a99c6bdfee72fbb8fbcf893e63ef3f54658bAmith Yamasani new LinkedHashMap<String, ArrayList<String>>(); 37856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana while (cursor.moveToNext()) { 37956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final long accountId = cursor.getLong(0); 38056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final String accountType = cursor.getString(1); 38156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final String accountName = cursor.getString(2); 3826ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey 3836ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey if (!knownAuth.contains(AuthenticatorDescription.newKey(accountType))) { 3846eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey Slog.w(TAG, "deleting account " + accountName + " because type " 38556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + accountType + " no longer has a registered authenticator"); 38656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana db.delete(TABLE_ACCOUNTS, ACCOUNTS_ID + "=" + accountId, null); 38756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana accountDeleted = true; 38856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final Account account = new Account(accountName, accountType); 38904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.userDataCache.remove(account); 39004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.authTokenCache.remove(account); 39156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } else { 39256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana ArrayList<String> accountNames = accountNamesByType.get(accountType); 39356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (accountNames == null) { 39456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana accountNames = new ArrayList<String>(); 39556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana accountNamesByType.put(accountType, accountNames); 39656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 39756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana accountNames.add(accountName); 39856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 39956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 4002f36229db823d152f3efd879e751e81a601a75b0Andy McFadden for (Map.Entry<String, ArrayList<String>> cur 401f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana : accountNamesByType.entrySet()) { 40256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final String accountType = cur.getKey(); 40356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final ArrayList<String> accountNames = cur.getValue(); 40456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final Account[] accountsForType = new Account[accountNames.size()]; 40556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana int i = 0; 40656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana for (String accountName : accountNames) { 40756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana accountsForType[i] = new Account(accountName, accountType); 40856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana ++i; 40956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 41004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.accountCache.put(accountType, accountsForType); 411afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana } 412f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } finally { 413f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana cursor.close(); 414f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (accountDeleted) { 41504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani sendAccountsChangedBroadcast(accounts.userId); 416f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 417afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana } 418afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana } 4193ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintana } 4203ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintana 42104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private UserAccounts getUserAccountsForCaller() { 422f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackborn return getUserAccounts(UserHandle.getCallingUserId()); 42304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 42404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani 42504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani protected UserAccounts getUserAccounts(int userId) { 42604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (mUsers) { 42704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = mUsers.get(userId); 42804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani if (accounts == null) { 4290c19bf524493f2feedf442d390c878fd1ca66d7bAmith Yamasani accounts = initUserLocked(userId); 43004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani mUsers.append(userId, accounts); 43104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 43204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani return accounts; 43304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 43404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 43504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani 436135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani private void onUserRemoved(Intent intent) { 4372a00329c6d55c6cd9166e01963d7410e95d80d21Amith Yamasani int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); 438135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani if (userId < 1) return; 439135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani 440135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani UserAccounts accounts; 441135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani synchronized (mUsers) { 442135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani accounts = mUsers.get(userId); 443135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani mUsers.remove(userId); 444135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani } 445135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani if (accounts == null) { 446135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani File dbFile = new File(getDatabaseName(userId)); 447135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani dbFile.delete(); 448135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani return; 449135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani } 450135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani 451135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani synchronized (accounts.cacheLock) { 452135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani accounts.openHelper.close(); 453135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani File dbFile = new File(getDatabaseName(userId)); 454135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani dbFile.delete(); 455135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani } 456135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani } 457135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani 45867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani private void onUserStarted(Intent intent) { 45967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); 46067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani if (userId < 1) return; 46167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani 46267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani // Check if there's a shared account that needs to be created as an account 46367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani Account[] sharedAccounts = getSharedAccountsAsUser(userId); 46467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani if (sharedAccounts == null || sharedAccounts.length == 0) return; 46567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani Account[] accounts = getAccountsAsUser(null, userId); 46667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani for (Account sa : sharedAccounts) { 46767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani if (ArrayUtils.contains(accounts, sa)) continue; 46867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani // Account doesn't exist. Copy it now. 46967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani copyAccountToUser(sa, UserHandle.USER_OWNER, userId); 47067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 47167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 47267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani 4736ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey @Override 4746ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey public void onServiceChanged(AuthenticatorDescription desc, int userId, boolean removed) { 4756eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey validateAccountsInternal(getUserAccounts(userId), false /* invalidateAuthenticatorCache */); 476603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 477603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 47809e7e0ef8bcd8b7b78b79fb570de2032871f0c97Jatin Lodhia @Override 479a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public String getPassword(Account account) { 48056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 48156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "getPassword: " + account 48256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 48356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 48456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 485382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 486d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkAuthenticateAccountsPermission(account); 487d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 48804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 48926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 490603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana try { 49104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani return readPasswordInternal(accounts, account); 492603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } finally { 49326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 494603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 495603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 496603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 49704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private String readPasswordInternal(UserAccounts accounts, Account account) { 49831957f1badbb900bbfe211317e1ea992d650a72dFred Quintana if (account == null) { 49931957f1badbb900bbfe211317e1ea992d650a72dFred Quintana return null; 50031957f1badbb900bbfe211317e1ea992d650a72dFred Quintana } 50131957f1badbb900bbfe211317e1ea992d650a72dFred Quintana 50204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 50304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getReadableDatabase(); 504f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana Cursor cursor = db.query(TABLE_ACCOUNTS, new String[]{ACCOUNTS_PASSWORD}, 505f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?", 506f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana new String[]{account.name, account.type}, null, null, null); 507f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana try { 508f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (cursor.moveToNext()) { 509f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return cursor.getString(0); 510f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 511f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return null; 512f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } finally { 513f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana cursor.close(); 514ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 515ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 516ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 517ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 51809e7e0ef8bcd8b7b78b79fb570de2032871f0c97Jatin Lodhia @Override 519a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public String getUserData(Account account, String key) { 52056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 52156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "getUserData: " + account 52256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", key " + key 52356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 52456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 52556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 526382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 527382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (key == null) throw new IllegalArgumentException("key is null"); 528d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkAuthenticateAccountsPermission(account); 52904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 53026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 531603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana try { 53204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani return readUserDataInternal(accounts, account, key); 533ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } finally { 534ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana restoreCallingIdentity(identityToken); 535ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 536ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 537ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 53809e7e0ef8bcd8b7b78b79fb570de2032871f0c97Jatin Lodhia @Override 5399788976b1465ce982b5ae7c741345edd0ecd9322Fred Quintana public AuthenticatorDescription[] getAuthenticatorTypes() { 54056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 54156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "getAuthenticatorTypes: " 54256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + "caller's uid " + Binder.getCallingUid() 54356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 54456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 5456ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey final int userId = UserHandle.getCallingUserId(); 5466ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey final long identityToken = clearCallingIdentity(); 54726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 5489788976b1465ce982b5ae7c741345edd0ecd9322Fred Quintana Collection<AccountAuthenticatorCache.ServiceInfo<AuthenticatorDescription>> 5496ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey authenticatorCollection = mAuthenticatorCache.getAllServices(userId); 5509788976b1465ce982b5ae7c741345edd0ecd9322Fred Quintana AuthenticatorDescription[] types = 5519788976b1465ce982b5ae7c741345edd0ecd9322Fred Quintana new AuthenticatorDescription[authenticatorCollection.size()]; 55226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana int i = 0; 5539788976b1465ce982b5ae7c741345edd0ecd9322Fred Quintana for (AccountAuthenticatorCache.ServiceInfo<AuthenticatorDescription> authenticator 554718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana : authenticatorCollection) { 555718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana types[i] = authenticator.type; 55626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana i++; 55726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 55826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana return types; 55926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 56026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 561a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 562a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 563a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 5643df7d697ca86ee2081bcfba31bcbd3ae4f4bcdf8Jatin Lodhia @Override 56527db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani public boolean addAccountExplicitly(Account account, String password, Bundle extras) { 56656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 56727db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani Log.v(TAG, "addAccountExplicitly: " + account 56856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 56956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 57056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 571382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 572d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkAuthenticateAccountsPermission(account); 5733df7d697ca86ee2081bcfba31bcbd3ae4f4bcdf8Jatin Lodhia /* 5743df7d697ca86ee2081bcfba31bcbd3ae4f4bcdf8Jatin Lodhia * Child users are not allowed to add accounts. Only the accounts that are 5753df7d697ca86ee2081bcfba31bcbd3ae4f4bcdf8Jatin Lodhia * shared by the parent profile can be added to child profile. 5763df7d697ca86ee2081bcfba31bcbd3ae4f4bcdf8Jatin Lodhia * 5773df7d697ca86ee2081bcfba31bcbd3ae4f4bcdf8Jatin Lodhia * TODO: Only allow accounts that were shared to be added by 5783df7d697ca86ee2081bcfba31bcbd3ae4f4bcdf8Jatin Lodhia * a limited user. 5793df7d697ca86ee2081bcfba31bcbd3ae4f4bcdf8Jatin Lodhia */ 580d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 58104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 582603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana // fails if the account already exists 58326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 584603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana try { 58567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani return addAccountInternal(accounts, account, password, extras, false); 58667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } finally { 58767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani restoreCallingIdentity(identityToken); 58867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 58967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 59067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani 59167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani private boolean copyAccountToUser(final Account account, int userFrom, int userTo) { 59267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani final UserAccounts fromAccounts = getUserAccounts(userFrom); 59367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani final UserAccounts toAccounts = getUserAccounts(userTo); 59467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani if (fromAccounts == null || toAccounts == null) { 59567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani return false; 59667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 59767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani 59867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani long identityToken = clearCallingIdentity(); 59967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani try { 60067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani new Session(fromAccounts, null, account.type, false, 60167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani false /* stripAuthTokenFromResult */) { 6025bab9daf3cf66f4de19f8757e386030e8bef23ceCarlos Valdivia @Override 60367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani protected String toDebugString(long now) { 60467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani return super.toDebugString(now) + ", getAccountCredentialsForClone" 60567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani + ", " + account.type; 60667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 60767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani 6085bab9daf3cf66f4de19f8757e386030e8bef23ceCarlos Valdivia @Override 60967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani public void run() throws RemoteException { 61067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani mAuthenticator.getAccountCredentialsForCloning(this, account); 61167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 61267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani 6135bab9daf3cf66f4de19f8757e386030e8bef23ceCarlos Valdivia @Override 61467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani public void onResult(Bundle result) { 61567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani if (result != null) { 61667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani if (result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT, false)) { 61767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani // Create a Session for the target user and pass in the bundle 61867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani completeCloningAccount(result, account, toAccounts); 61967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 62067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani return; 62167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } else { 62267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani super.onResult(result); 62367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 62467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 62567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani }.bind(); 626ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } finally { 627ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana restoreCallingIdentity(identityToken); 628ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 62967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani return true; 63067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 63167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani 63267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani void completeCloningAccount(final Bundle result, final Account account, 63367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani final UserAccounts targetUser) { 63467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani long id = clearCallingIdentity(); 63567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani try { 63667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani new Session(targetUser, null, account.type, false, 63767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani false /* stripAuthTokenFromResult */) { 6385bab9daf3cf66f4de19f8757e386030e8bef23ceCarlos Valdivia @Override 63967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani protected String toDebugString(long now) { 64067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani return super.toDebugString(now) + ", getAccountCredentialsForClone" 64167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani + ", " + account.type; 64267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 64367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani 6445bab9daf3cf66f4de19f8757e386030e8bef23ceCarlos Valdivia @Override 64567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani public void run() throws RemoteException { 6465be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani // Confirm that the owner's account still exists before this step. 6475be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani UserAccounts owner = getUserAccounts(UserHandle.USER_OWNER); 6485be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani synchronized (owner.cacheLock) { 6495be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani Account[] ownerAccounts = getAccounts(UserHandle.USER_OWNER); 6505be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani for (Account acc : ownerAccounts) { 6515be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani if (acc.equals(account)) { 6525be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani mAuthenticator.addAccountFromCredentials(this, account, result); 6535be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani break; 6545be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani } 6555be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani } 6565be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani } 65767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 65867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani 6595bab9daf3cf66f4de19f8757e386030e8bef23ceCarlos Valdivia @Override 66067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani public void onResult(Bundle result) { 66167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani if (result != null) { 66267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani if (result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT, false)) { 66367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani // TODO: Anything? 66467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } else { 66567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani // TODO: Show error notification 66667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani // TODO: Should we remove the shadow account to avoid retries? 66767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 66867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani return; 66967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } else { 67067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani super.onResult(result); 67167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 67267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 67367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani 6745bab9daf3cf66f4de19f8757e386030e8bef23ceCarlos Valdivia @Override 67567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani public void onError(int errorCode, String errorMessage) { 67667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani super.onError(errorCode, errorMessage); 67767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani // TODO: Show error notification to user 67867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani // TODO: Should we remove the shadow account so that it doesn't keep trying? 67967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 68067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani 68167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani }.bind(); 68267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } finally { 68367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani restoreCallingIdentity(id); 68467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 685ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 686ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 68704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private boolean addAccountInternal(UserAccounts accounts, Account account, String password, 68867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani Bundle extras, boolean restricted) { 689743dfad2a51e016ddb741c104317637089187753Fred Quintana if (account == null) { 690743dfad2a51e016ddb741c104317637089187753Fred Quintana return false; 691743dfad2a51e016ddb741c104317637089187753Fred Quintana } 69204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 69304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getWritableDatabase(); 694f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.beginTransaction(); 695f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana try { 696f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana long numMatches = DatabaseUtils.longForQuery(db, 697f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana "select count(*) from " + TABLE_ACCOUNTS 698f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana + " WHERE " + ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?", 699f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana new String[]{account.name, account.type}); 700f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (numMatches > 0) { 701f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana Log.w(TAG, "insertAccountIntoDatabase: " + account 702f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana + ", skipping since the account already exists"); 703f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return false; 704f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 705f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana ContentValues values = new ContentValues(); 706f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana values.put(ACCOUNTS_NAME, account.name); 707f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana values.put(ACCOUNTS_TYPE, account.type); 708f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana values.put(ACCOUNTS_PASSWORD, password); 709f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana long accountId = db.insert(TABLE_ACCOUNTS, ACCOUNTS_NAME, values); 710f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (accountId < 0) { 711f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana Log.w(TAG, "insertAccountIntoDatabase: " + account 712f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana + ", skipping the DB insert failed"); 713f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return false; 714f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 715f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (extras != null) { 716f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana for (String key : extras.keySet()) { 717f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana final String value = extras.getString(key); 718f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (insertExtraLocked(db, accountId, key, value) < 0) { 719f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana Log.w(TAG, "insertAccountIntoDatabase: " + account 720f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana + ", skipping since insertExtra failed for key " + key); 721f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return false; 722f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 723603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 724603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 725f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.setTransactionSuccessful(); 72604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani insertAccountIntoCacheLocked(accounts, account); 727f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } finally { 728f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.endTransaction(); 729603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 73004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani sendAccountsChangedBroadcast(accounts.userId); 7315be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani } 7325be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani if (accounts.userId == UserHandle.USER_OWNER) { 7335be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani addAccountToLimitedUsers(account); 7345be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani } 7355be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani return true; 7365be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani } 7375be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani 7385be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani /** 7395be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani * Adds the account to all limited users as shared accounts. If the user is currently 7405be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani * running, then clone the account too. 7415be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani * @param account the account to share with limited users 7425be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani */ 7435be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani private void addAccountToLimitedUsers(Account account) { 744f4c240e68a3da9f1ebf42267c88af40c19ff49daMita Yun List<UserInfo> users = getUserManager().getUsers(); 7455be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani for (UserInfo user : users) { 7465be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani if (user.isRestricted()) { 7475be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani addSharedAccountAsUser(account, user.id); 7485be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani try { 7495be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani if (ActivityManagerNative.getDefault().isUserRunning(user.id, false)) { 7505be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani mMessageHandler.sendMessage(mMessageHandler.obtainMessage( 7515be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani MESSAGE_COPY_SHARED_ACCOUNT, UserHandle.USER_OWNER, user.id, 7525be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani account)); 7535be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani } 7545be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani } catch (RemoteException re) { 7555be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani // Shouldn't happen 7565be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani } 7575be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani } 758603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 759603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 760603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 761f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana private long insertExtraLocked(SQLiteDatabase db, long accountId, String key, String value) { 762603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana ContentValues values = new ContentValues(); 763603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana values.put(EXTRAS_KEY, key); 764603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana values.put(EXTRAS_ACCOUNTS_ID, accountId); 765603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana values.put(EXTRAS_VALUE, value); 766603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana return db.insert(TABLE_EXTRAS, EXTRAS_KEY, values); 767603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 768603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 76909e7e0ef8bcd8b7b78b79fb570de2032871f0c97Jatin Lodhia @Override 7703084a6f80180506ce26fe4773d9a19f004b7f625Fred Quintana public void hasFeatures(IAccountManagerResponse response, 771bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana Account account, String[] features) { 77256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 77356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "hasFeatures: " + account 77456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", response " + response 77556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", features " + stringArrayToString(features) 77656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 77756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 77856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 779382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (response == null) throw new IllegalArgumentException("response is null"); 780382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 781382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (features == null) throw new IllegalArgumentException("features is null"); 782bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana checkReadAccountsPermission(); 78304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 784bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana long identityToken = clearCallingIdentity(); 785bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana try { 78604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani new TestFeaturesSession(accounts, response, account, features).bind(); 787bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } finally { 788bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana restoreCallingIdentity(identityToken); 789bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 790bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 791bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana 792bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana private class TestFeaturesSession extends Session { 793bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana private final String[] mFeatures; 794bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana private final Account mAccount; 795bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana 79604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani public TestFeaturesSession(UserAccounts accounts, IAccountManagerResponse response, 797bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana Account account, String[] features) { 79804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani super(accounts, response, account.type, false /* expectActivityLaunch */, 7998570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana true /* stripAuthTokenFromResult */); 800bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana mFeatures = features; 801bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana mAccount = account; 802bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 803bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana 8045bab9daf3cf66f4de19f8757e386030e8bef23ceCarlos Valdivia @Override 805bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana public void run() throws RemoteException { 806bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana try { 807bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana mAuthenticator.hasFeatures(this, mAccount, mFeatures); 808bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } catch (RemoteException e) { 809bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana onError(AccountManager.ERROR_CODE_REMOTE_EXCEPTION, "remote exception"); 810bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 811bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 812bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana 8135bab9daf3cf66f4de19f8757e386030e8bef23ceCarlos Valdivia @Override 814bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana public void onResult(Bundle result) { 815bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana IAccountManagerResponse response = getResponseAndClose(); 816bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana if (response != null) { 817bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana try { 818bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana if (result == null) { 819166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana response.onError(AccountManager.ERROR_CODE_INVALID_RESPONSE, "null bundle"); 820bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana return; 821bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 82256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 82356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, getClass().getSimpleName() + " calling onResult() on response " 82456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + response); 82556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 826bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana final Bundle newResult = new Bundle(); 827bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana newResult.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, 828bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT, false)); 829bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana response.onResult(newResult); 830bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } catch (RemoteException e) { 831bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana // if the caller is dead then there is no one to care about remote exceptions 832bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 833bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana Log.v(TAG, "failure while notifying response", e); 834bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 835bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 836bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 837bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 838bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana 8395bab9daf3cf66f4de19f8757e386030e8bef23ceCarlos Valdivia @Override 840bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana protected String toDebugString(long now) { 8413084a6f80180506ce26fe4773d9a19f004b7f625Fred Quintana return super.toDebugString(now) + ", hasFeatures" 842bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana + ", " + mAccount 843bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana + ", " + (mFeatures != null ? TextUtils.join(",", mFeatures) : null); 844bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 845bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 846307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana 84709e7e0ef8bcd8b7b78b79fb570de2032871f0c97Jatin Lodhia @Override 848ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana public void removeAccount(IAccountManagerResponse response, Account account) { 84956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 85056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "removeAccount: " + account 85156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", response " + response 85256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 85356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 85456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 855382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (response == null) throw new IllegalArgumentException("response is null"); 856382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 857d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkManageAccountsPermission(); 85850cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn UserHandle user = Binder.getCallingUserHandle(); 85904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 860e4cf73437a18c1444055f88a1fcc0d146ec23ac5Amith Yamasani if (!canUserModifyAccounts(Binder.getCallingUid())) { 861e4cf73437a18c1444055f88a1fcc0d146ec23ac5Amith Yamasani try { 862e4cf73437a18c1444055f88a1fcc0d146ec23ac5Amith Yamasani response.onError(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION, 863e4cf73437a18c1444055f88a1fcc0d146ec23ac5Amith Yamasani "User cannot modify accounts"); 864e4cf73437a18c1444055f88a1fcc0d146ec23ac5Amith Yamasani } catch (RemoteException re) { 865e4cf73437a18c1444055f88a1fcc0d146ec23ac5Amith Yamasani } 866e4cf73437a18c1444055f88a1fcc0d146ec23ac5Amith Yamasani } 867e4cf73437a18c1444055f88a1fcc0d146ec23ac5Amith Yamasani 86826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 869ec0c4f4183630a64c2b2cc8f961dc7e11cc628caCostin Manolache 87050cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn cancelNotification(getSigninRequiredNotificationId(accounts, account), user); 87104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized(accounts.credentialsPermissionNotificationIds) { 872ec0c4f4183630a64c2b2cc8f961dc7e11cc628caCostin Manolache for (Pair<Pair<Account, String>, Integer> pair: 87304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.credentialsPermissionNotificationIds.keySet()) { 874ec0c4f4183630a64c2b2cc8f961dc7e11cc628caCostin Manolache if (account.equals(pair.first.first)) { 87504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani int id = accounts.credentialsPermissionNotificationIds.get(pair); 87650cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn cancelNotification(id, user); 877ec0c4f4183630a64c2b2cc8f961dc7e11cc628caCostin Manolache } 878ec0c4f4183630a64c2b2cc8f961dc7e11cc628caCostin Manolache } 879ec0c4f4183630a64c2b2cc8f961dc7e11cc628caCostin Manolache } 880ec0c4f4183630a64c2b2cc8f961dc7e11cc628caCostin Manolache 88126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 88204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani new RemoveAccountSession(accounts, response, account).bind(); 88326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 88426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 885a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 886603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 887603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 888ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana private class RemoveAccountSession extends Session { 889ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana final Account mAccount; 89004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani public RemoveAccountSession(UserAccounts accounts, IAccountManagerResponse response, 89104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani Account account) { 89204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani super(accounts, response, account.type, false /* expectActivityLaunch */, 8938570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana true /* stripAuthTokenFromResult */); 894ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana mAccount = account; 895ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 896ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 8975bab9daf3cf66f4de19f8757e386030e8bef23ceCarlos Valdivia @Override 898ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana protected String toDebugString(long now) { 899ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana return super.toDebugString(now) + ", removeAccount" 900ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana + ", account " + mAccount; 901ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 902ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 9035bab9daf3cf66f4de19f8757e386030e8bef23ceCarlos Valdivia @Override 904ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana public void run() throws RemoteException { 905ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana mAuthenticator.getAccountRemovalAllowed(this, mAccount); 906ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 907ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 9085bab9daf3cf66f4de19f8757e386030e8bef23ceCarlos Valdivia @Override 909ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana public void onResult(Bundle result) { 910f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana if (result != null && result.containsKey(AccountManager.KEY_BOOLEAN_RESULT) 911f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana && !result.containsKey(AccountManager.KEY_INTENT)) { 912f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana final boolean removalAllowed = result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT); 913ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana if (removalAllowed) { 91404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani removeAccountInternal(mAccounts, mAccount); 915ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 916ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana IAccountManagerResponse response = getResponseAndClose(); 917ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana if (response != null) { 91856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 91956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, getClass().getSimpleName() + " calling onResult() on response " 92056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + response); 92156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 922ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana Bundle result2 = new Bundle(); 923f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana result2.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, removalAllowed); 924ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana try { 925ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana response.onResult(result2); 926ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } catch (RemoteException e) { 927ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana // ignore 928ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 929ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 930ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 931ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana super.onResult(result); 932ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 933ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 934ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 93504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani /* For testing */ 936f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana protected void removeAccountInternal(Account account) { 93704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani removeAccountInternal(getUserAccountsForCaller(), account); 93804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 93904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani 94004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private void removeAccountInternal(UserAccounts accounts, Account account) { 94104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 94204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getWritableDatabase(); 943f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.delete(TABLE_ACCOUNTS, ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?", 944f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana new String[]{account.name, account.type}); 94504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani removeAccountFromCacheLocked(accounts, account); 94604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani sendAccountsChangedBroadcast(accounts.userId); 947f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 94867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani if (accounts.userId == UserHandle.USER_OWNER) { 94967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani // Owner's account was removed, remove from any users that are sharing 95067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani // this account. 95167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani long id = Binder.clearCallingIdentity(); 95267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani try { 95367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani List<UserInfo> users = mUserManager.getUsers(true); 95467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani for (UserInfo user : users) { 95567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani if (!user.isPrimary() && user.isRestricted()) { 95667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani removeSharedAccountAsUser(account, user.id); 95767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 95867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 95967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } finally { 96067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani Binder.restoreCallingIdentity(id); 96167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 96267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 963ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 964ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 965a12fccf57d5ec289793699d9b22ff45daccd3933Maggie Benthall @Override 966a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void invalidateAuthToken(String accountType, String authToken) { 96756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 96856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "invalidateAuthToken: accountType " + accountType 96956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 97056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 97156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 972382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (accountType == null) throw new IllegalArgumentException("accountType is null"); 973382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (authToken == null) throw new IllegalArgumentException("authToken is null"); 974b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana checkManageAccountsOrUseCredentialsPermissions(); 97504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 97626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 977603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana try { 97804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 97904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getWritableDatabase(); 980f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.beginTransaction(); 981f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana try { 98204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani invalidateAuthTokenLocked(accounts, db, accountType, authToken); 983f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.setTransactionSuccessful(); 984f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } finally { 985f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.endTransaction(); 986f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 98726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 988603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } finally { 98926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 990603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 991603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 992603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 99304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private void invalidateAuthTokenLocked(UserAccounts accounts, SQLiteDatabase db, 99404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani String accountType, String authToken) { 995ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana if (authToken == null || accountType == null) { 996ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana return; 997ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 9983326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana Cursor cursor = db.rawQuery( 9993326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana "SELECT " + TABLE_AUTHTOKENS + "." + AUTHTOKENS_ID 10003326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + ", " + TABLE_ACCOUNTS + "." + ACCOUNTS_NAME 10013326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + ", " + TABLE_AUTHTOKENS + "." + AUTHTOKENS_TYPE 10023326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + " FROM " + TABLE_ACCOUNTS 10033326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + " JOIN " + TABLE_AUTHTOKENS 10043326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + " ON " + TABLE_ACCOUNTS + "." + ACCOUNTS_ID 10053326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + " = " + AUTHTOKENS_ACCOUNTS_ID 10063326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + " WHERE " + AUTHTOKENS_AUTHTOKEN + " = ? AND " 10073326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + TABLE_ACCOUNTS + "." + ACCOUNTS_TYPE + " = ?", 10083326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana new String[]{authToken, accountType}); 10093326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana try { 10103326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana while (cursor.moveToNext()) { 10113326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana long authTokenId = cursor.getLong(0); 10123326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana String accountName = cursor.getString(1); 10133326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana String authTokenType = cursor.getString(2); 10143326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana db.delete(TABLE_AUTHTOKENS, AUTHTOKENS_ID + "=" + authTokenId, null); 101504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani writeAuthTokenIntoCacheLocked(accounts, db, new Account(accountName, accountType), 1016f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana authTokenType, null); 1017603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 10183326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } finally { 10193326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana cursor.close(); 1020603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1021603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1022603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 102304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private boolean saveAuthTokenToDatabase(UserAccounts accounts, Account account, String type, 102404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani String authToken) { 102531957f1badbb900bbfe211317e1ea992d650a72dFred Quintana if (account == null || type == null) { 102631957f1badbb900bbfe211317e1ea992d650a72dFred Quintana return false; 102731957f1badbb900bbfe211317e1ea992d650a72dFred Quintana } 102850cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn cancelNotification(getSigninRequiredNotificationId(accounts, account), 102950cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn new UserHandle(accounts.userId)); 103004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 103104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getWritableDatabase(); 1032f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.beginTransaction(); 1033f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana try { 1034f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana long accountId = getAccountIdLocked(db, account); 1035f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (accountId < 0) { 1036f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return false; 1037f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 1038f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.delete(TABLE_AUTHTOKENS, 1039f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana AUTHTOKENS_ACCOUNTS_ID + "=" + accountId + " AND " + AUTHTOKENS_TYPE + "=?", 1040f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana new String[]{type}); 1041f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana ContentValues values = new ContentValues(); 1042f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana values.put(AUTHTOKENS_ACCOUNTS_ID, accountId); 1043f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana values.put(AUTHTOKENS_TYPE, type); 1044f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana values.put(AUTHTOKENS_AUTHTOKEN, authToken); 1045f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (db.insert(TABLE_AUTHTOKENS, AUTHTOKENS_AUTHTOKEN, values) >= 0) { 1046f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.setTransactionSuccessful(); 104704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani writeAuthTokenIntoCacheLocked(accounts, db, account, type, authToken); 1048f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return true; 1049f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 10503326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana return false; 1051f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } finally { 1052f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.endTransaction(); 10533326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 1054603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1055603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1056603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 105709e7e0ef8bcd8b7b78b79fb570de2032871f0c97Jatin Lodhia @Override 1058a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public String peekAuthToken(Account account, String authTokenType) { 105956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 106056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "peekAuthToken: " + account 106156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", authTokenType " + authTokenType 106256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 106356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 106456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 1065382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 1066382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null"); 1067d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkAuthenticateAccountsPermission(account); 106804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 106926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 107026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 107104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani return readAuthTokenInternal(accounts, account, authTokenType); 107226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 107326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 1074603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1075603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1076603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 107709e7e0ef8bcd8b7b78b79fb570de2032871f0c97Jatin Lodhia @Override 1078a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void setAuthToken(Account account, String authTokenType, String authToken) { 107956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 108056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "setAuthToken: " + account 108156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", authTokenType " + authTokenType 108256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 108356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 108456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 1085382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 1086382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null"); 1087d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkAuthenticateAccountsPermission(account); 108804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 108926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 109026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 109104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani saveAuthTokenToDatabase(accounts, account, authTokenType, authToken); 109226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 109326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 109426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1095603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1096603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 109709e7e0ef8bcd8b7b78b79fb570de2032871f0c97Jatin Lodhia @Override 1098a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void setPassword(Account account, String password) { 109956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 110056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "setAuthToken: " + account 110156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 110256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 110356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 1104382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 1105d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkAuthenticateAccountsPermission(account); 110604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 110726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 110826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 110904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani setPasswordInternal(accounts, account, password); 111026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 111126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 111226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1113603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1114603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 111504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private void setPasswordInternal(UserAccounts accounts, Account account, String password) { 111631957f1badbb900bbfe211317e1ea992d650a72dFred Quintana if (account == null) { 111731957f1badbb900bbfe211317e1ea992d650a72dFred Quintana return; 111831957f1badbb900bbfe211317e1ea992d650a72dFred Quintana } 111904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 112004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getWritableDatabase(); 1121f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.beginTransaction(); 1122f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana try { 1123f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana final ContentValues values = new ContentValues(); 1124f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana values.put(ACCOUNTS_PASSWORD, password); 1125f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana final long accountId = getAccountIdLocked(db, account); 1126f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (accountId >= 0) { 1127f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana final String[] argsAccountId = {String.valueOf(accountId)}; 1128f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.update(TABLE_ACCOUNTS, values, ACCOUNTS_ID + "=?", argsAccountId); 1129f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.delete(TABLE_AUTHTOKENS, AUTHTOKENS_ACCOUNTS_ID + "=?", argsAccountId); 113004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.authTokenCache.remove(account); 1131f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.setTransactionSuccessful(); 1132f5ffe89e736caee1419f0acb469565d5100b8fb8Costin Manolache } 1133f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } finally { 1134f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.endTransaction(); 1135d4a9d6c42bb412e27a8383aaacd051419d98a662Fred Quintana } 113604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani sendAccountsChangedBroadcast(accounts.userId); 1137d4a9d6c42bb412e27a8383aaacd051419d98a662Fred Quintana } 11383ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintana } 11393ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintana 114004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private void sendAccountsChangedBroadcast(int userId) { 114156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.i(TAG, "the accounts changed, sending broadcast of " 114256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ACCOUNTS_CHANGED_INTENT.getAction()); 114379af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn mContext.sendBroadcastAsUser(ACCOUNTS_CHANGED_INTENT, new UserHandle(userId)); 11443326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 11453326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 114609e7e0ef8bcd8b7b78b79fb570de2032871f0c97Jatin Lodhia @Override 1147a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void clearPassword(Account account) { 114856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 114956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "clearPassword: " + account 115056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 115156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 115256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 1153382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 1154d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkManageAccountsPermission(); 115504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 115626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 115726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 115804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani setPasswordInternal(accounts, account, null); 115926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 116026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 116126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1162603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1163603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 116409e7e0ef8bcd8b7b78b79fb570de2032871f0c97Jatin Lodhia @Override 1165a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void setUserData(Account account, String key, String value) { 116656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 116756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "setUserData: " + account 116856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", key " + key 116956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 117056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 117156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 1172382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (key == null) throw new IllegalArgumentException("key is null"); 1173382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 1174d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkAuthenticateAccountsPermission(account); 117504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 117626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 1177603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana try { 117804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani setUserdataInternal(accounts, account, key, value); 1179ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } finally { 1180ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana restoreCallingIdentity(identityToken); 1181ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 1182ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 1183ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 118404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private void setUserdataInternal(UserAccounts accounts, Account account, String key, 118504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani String value) { 118631957f1badbb900bbfe211317e1ea992d650a72dFred Quintana if (account == null || key == null) { 118731957f1badbb900bbfe211317e1ea992d650a72dFred Quintana return; 118831957f1badbb900bbfe211317e1ea992d650a72dFred Quintana } 118904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 119004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getWritableDatabase(); 1191f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.beginTransaction(); 1192f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana try { 1193f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana long accountId = getAccountIdLocked(db, account); 1194f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (accountId < 0) { 1195ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana return; 119626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1197f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana long extrasId = getExtrasIdLocked(db, accountId, key); 1198f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (extrasId < 0 ) { 1199f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana extrasId = insertExtraLocked(db, accountId, key, value); 1200f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (extrasId < 0) { 1201f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return; 1202f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 1203f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } else { 1204f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana ContentValues values = new ContentValues(); 1205f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana values.put(EXTRAS_VALUE, value); 1206f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (1 != db.update(TABLE_EXTRAS, values, EXTRAS_ID + "=" + extrasId, null)) { 1207f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return; 1208f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 1209ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 1210f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 121104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani writeUserDataIntoCacheLocked(accounts, db, account, key, value); 1212f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.setTransactionSuccessful(); 1213f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } finally { 1214f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.endTransaction(); 1215603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1216603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1217603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1218603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1219d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private void onResult(IAccountManagerResponse response, Bundle result) { 122056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (result == null) { 122156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.e(TAG, "the result is unexpectedly null", new Exception()); 122256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 122356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 122456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, getClass().getSimpleName() + " calling onResult() on response " 122556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + response); 122656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 1227d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana try { 1228d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana response.onResult(result); 1229d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } catch (RemoteException e) { 1230d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana // if the caller is dead then there is no one to care about remote 1231d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana // exceptions 1232d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 1233d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Log.v(TAG, "failure while notifying response", e); 1234d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1235d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1236d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1237d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 123809e7e0ef8bcd8b7b78b79fb570de2032871f0c97Jatin Lodhia @Override 1239d9640ec712806508877868d08aafaa2d715ff441Fred Quintana public void getAuthTokenLabel(IAccountManagerResponse response, final String accountType, 1240d9640ec712806508877868d08aafaa2d715ff441Fred Quintana final String authTokenType) 1241d9640ec712806508877868d08aafaa2d715ff441Fred Quintana throws RemoteException { 1242d9640ec712806508877868d08aafaa2d715ff441Fred Quintana if (accountType == null) throw new IllegalArgumentException("accountType is null"); 12435f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null"); 12445f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache 1245d9640ec712806508877868d08aafaa2d715ff441Fred Quintana final int callingUid = getCallingUid(); 1246d9640ec712806508877868d08aafaa2d715ff441Fred Quintana clearCallingIdentity(); 124727db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani if (callingUid != Process.SYSTEM_UID) { 1248d9640ec712806508877868d08aafaa2d715ff441Fred Quintana throw new SecurityException("can only call from system"); 1249d9640ec712806508877868d08aafaa2d715ff441Fred Quintana } 1250f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackborn UserAccounts accounts = getUserAccounts(UserHandle.getUserId(callingUid)); 12515f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache long identityToken = clearCallingIdentity(); 12525f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache try { 1253d9640ec712806508877868d08aafaa2d715ff441Fred Quintana new Session(accounts, response, accountType, false, 12545f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache false /* stripAuthTokenFromResult */) { 12555bab9daf3cf66f4de19f8757e386030e8bef23ceCarlos Valdivia @Override 12565f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache protected String toDebugString(long now) { 12575f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache return super.toDebugString(now) + ", getAuthTokenLabel" 1258d9640ec712806508877868d08aafaa2d715ff441Fred Quintana + ", " + accountType 12595f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache + ", authTokenType " + authTokenType; 12605f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache } 12615f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache 12625bab9daf3cf66f4de19f8757e386030e8bef23ceCarlos Valdivia @Override 12635f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache public void run() throws RemoteException { 12645f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache mAuthenticator.getAuthTokenLabel(this, authTokenType); 12655f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache } 12665f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache 12675bab9daf3cf66f4de19f8757e386030e8bef23ceCarlos Valdivia @Override 12685f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache public void onResult(Bundle result) { 12695f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache if (result != null) { 12705f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache String label = result.getString(AccountManager.KEY_AUTH_TOKEN_LABEL); 12715f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache Bundle bundle = new Bundle(); 12725f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache bundle.putString(AccountManager.KEY_AUTH_TOKEN_LABEL, label); 12735f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache super.onResult(bundle); 12745f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache return; 12755f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache } else { 12765f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache super.onResult(result); 12775f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache } 12785f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache } 12795f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache }.bind(); 12805f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache } finally { 12815f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache restoreCallingIdentity(identityToken); 12825f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache } 12835f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache } 12845f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache 128509e7e0ef8bcd8b7b78b79fb570de2032871f0c97Jatin Lodhia @Override 1286a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void getAuthToken(IAccountManagerResponse response, final Account account, 1287a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana final String authTokenType, final boolean notifyOnAuthFailure, 1288c6684f9e9790e92960504e9b32f20f27003d9f37Costin Manolache final boolean expectActivityLaunch, Bundle loginOptionsIn) { 128956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 129056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "getAuthToken: " + account 129156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", response " + response 129256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", authTokenType " + authTokenType 129356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", notifyOnAuthFailure " + notifyOnAuthFailure 129456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", expectActivityLaunch " + expectActivityLaunch 129556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 129656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 129756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 1298382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (response == null) throw new IllegalArgumentException("response is null"); 129909e7e0ef8bcd8b7b78b79fb570de2032871f0c97Jatin Lodhia try { 130009e7e0ef8bcd8b7b78b79fb570de2032871f0c97Jatin Lodhia if (account == null) { 130109e7e0ef8bcd8b7b78b79fb570de2032871f0c97Jatin Lodhia Slog.w(TAG, "getAuthToken called with null account"); 130209e7e0ef8bcd8b7b78b79fb570de2032871f0c97Jatin Lodhia response.onError(AccountManager.ERROR_CODE_BAD_ARGUMENTS, "account is null"); 130309e7e0ef8bcd8b7b78b79fb570de2032871f0c97Jatin Lodhia return; 130409e7e0ef8bcd8b7b78b79fb570de2032871f0c97Jatin Lodhia } 130509e7e0ef8bcd8b7b78b79fb570de2032871f0c97Jatin Lodhia if (authTokenType == null) { 130609e7e0ef8bcd8b7b78b79fb570de2032871f0c97Jatin Lodhia Slog.w(TAG, "getAuthToken called with null authTokenType"); 130709e7e0ef8bcd8b7b78b79fb570de2032871f0c97Jatin Lodhia response.onError(AccountManager.ERROR_CODE_BAD_ARGUMENTS, "authTokenType is null"); 130809e7e0ef8bcd8b7b78b79fb570de2032871f0c97Jatin Lodhia return; 130909e7e0ef8bcd8b7b78b79fb570de2032871f0c97Jatin Lodhia } 131009e7e0ef8bcd8b7b78b79fb570de2032871f0c97Jatin Lodhia } catch (RemoteException e) { 131109e7e0ef8bcd8b7b78b79fb570de2032871f0c97Jatin Lodhia Slog.w(TAG, "Failed to report error back to the client." + e); 131209e7e0ef8bcd8b7b78b79fb570de2032871f0c97Jatin Lodhia return; 131309e7e0ef8bcd8b7b78b79fb570de2032871f0c97Jatin Lodhia } 131409e7e0ef8bcd8b7b78b79fb570de2032871f0c97Jatin Lodhia 1315d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkBinderPermission(Manifest.permission.USE_CREDENTIALS); 13164120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn final UserAccounts accounts = getUserAccountsForCaller(); 13176ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey final RegisteredServicesCache.ServiceInfo<AuthenticatorDescription> authenticatorInfo; 13186ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey authenticatorInfo = mAuthenticatorCache.getServiceInfo( 13196ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey AuthenticatorDescription.newKey(account.type), accounts.userId); 1320a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache final boolean customTokens = 1321a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache authenticatorInfo != null && authenticatorInfo.type.customTokens; 1322a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache 1323a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache // skip the check if customTokens 1324b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache final int callerUid = Binder.getCallingUid(); 1325a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache final boolean permissionGranted = customTokens || 1326a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache permissionIsGranted(account, authTokenType, callerUid); 1327a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache 1328c6684f9e9790e92960504e9b32f20f27003d9f37Costin Manolache final Bundle loginOptions = (loginOptionsIn == null) ? new Bundle() : 1329c6684f9e9790e92960504e9b32f20f27003d9f37Costin Manolache loginOptionsIn; 1330b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache // let authenticator know the identity of the caller 1331b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache loginOptions.putInt(AccountManager.KEY_CALLER_UID, callerUid); 1332b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache loginOptions.putInt(AccountManager.KEY_CALLER_PID, Binder.getCallingPid()); 1333b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache if (notifyOnAuthFailure) { 1334b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache loginOptions.putBoolean(AccountManager.KEY_NOTIFY_ON_FAILURE, true); 1335a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache } 13366ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey 133726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 133826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 1339d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana // if the caller has permission, do the peek. otherwise go the more expensive 1340d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana // route of starting a Session 1341a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache if (!customTokens && permissionGranted) { 134204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani String authToken = readAuthTokenInternal(accounts, account, authTokenType); 1343d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (authToken != null) { 134426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana Bundle result = new Bundle(); 1345f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana result.putString(AccountManager.KEY_AUTHTOKEN, authToken); 1346f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name); 1347f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana result.putString(AccountManager.KEY_ACCOUNT_TYPE, account.type); 1348d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana onResult(response, result); 1349d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana return; 1350a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1351a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1352603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 135304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani new Session(accounts, response, account.type, expectActivityLaunch, 13548570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana false /* stripAuthTokenFromResult */) { 13555bab9daf3cf66f4de19f8757e386030e8bef23ceCarlos Valdivia @Override 135626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana protected String toDebugString(long now) { 135726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana if (loginOptions != null) loginOptions.keySet(); 135826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana return super.toDebugString(now) + ", getAuthToken" 135926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana + ", " + account 136026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana + ", authTokenType " + authTokenType 136126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana + ", loginOptions " + loginOptions 136226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana + ", notifyOnAuthFailure " + notifyOnAuthFailure; 136326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1364a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 13655bab9daf3cf66f4de19f8757e386030e8bef23ceCarlos Valdivia @Override 136626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana public void run() throws RemoteException { 1367d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana // If the caller doesn't have permission then create and return the 1368d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana // "grant permission" intent instead of the "getAuthToken" intent. 1369d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (!permissionGranted) { 1370d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana mAuthenticator.getAuthTokenLabel(this, authTokenType); 1371d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } else { 1372d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana mAuthenticator.getAuthToken(this, account, authTokenType, loginOptions); 1373d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 137426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1375a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 13765bab9daf3cf66f4de19f8757e386030e8bef23ceCarlos Valdivia @Override 137726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana public void onResult(Bundle result) { 137826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana if (result != null) { 1379f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana if (result.containsKey(AccountManager.KEY_AUTH_TOKEN_LABEL)) { 1380d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Intent intent = newGrantCredentialsPermissionIntent(account, callerUid, 1381d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana new AccountAuthenticatorResponse(this), 1382d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana authTokenType, 1383f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana result.getString(AccountManager.KEY_AUTH_TOKEN_LABEL)); 1384d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Bundle bundle = new Bundle(); 1385f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana bundle.putParcelable(AccountManager.KEY_INTENT, intent); 1386d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana onResult(bundle); 1387d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana return; 1388d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1389f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana String authToken = result.getString(AccountManager.KEY_AUTHTOKEN); 139026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana if (authToken != null) { 1391f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana String name = result.getString(AccountManager.KEY_ACCOUNT_NAME); 1392f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana String type = result.getString(AccountManager.KEY_ACCOUNT_TYPE); 139326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana if (TextUtils.isEmpty(type) || TextUtils.isEmpty(name)) { 1394f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana onError(AccountManager.ERROR_CODE_INVALID_RESPONSE, 139526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana "the type and name should not be empty"); 139626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana return; 139726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1398a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache if (!customTokens) { 139904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani saveAuthTokenToDatabase(mAccounts, new Account(name, type), 1400a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache authTokenType, authToken); 1401a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache } 1402a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1403603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1404f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana Intent intent = result.getParcelable(AccountManager.KEY_INTENT); 1405d606045070dcf6a011e49a7711d2f17d8f2de8c1Costin Manolache if (intent != null && notifyOnAuthFailure && !customTokens) { 140604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani doNotification(mAccounts, 1407f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana account, result.getString(AccountManager.KEY_AUTH_FAILED_MESSAGE), 14084120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn intent, accounts.userId); 140926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1410a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 141126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana super.onResult(result); 1412a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 141326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana }.bind(); 141426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 141526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 141626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1417603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1418603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 14194120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn private void createNoCredentialsPermissionNotification(Account account, Intent intent, 14204120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn int userId) { 1421d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana int uid = intent.getIntExtra( 1422d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana GrantCredentialsPermissionActivity.EXTRAS_REQUESTING_UID, -1); 1423d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana String authTokenType = intent.getStringExtra( 1424d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana GrantCredentialsPermissionActivity.EXTRAS_AUTH_TOKEN_TYPE); 1425d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana String authTokenLabel = intent.getStringExtra( 1426d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana GrantCredentialsPermissionActivity.EXTRAS_AUTH_TOKEN_LABEL); 1427d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 1428d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Notification n = new Notification(android.R.drawable.stat_sys_warning, null, 1429d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 0 /* when */); 1430ee452ee5359cdfa3c3fbf6783722d3aaa2ec5ca6Eric Fischer final String titleAndSubtitle = 1431ee452ee5359cdfa3c3fbf6783722d3aaa2ec5ca6Eric Fischer mContext.getString(R.string.permission_request_notification_with_subtitle, 1432ee452ee5359cdfa3c3fbf6783722d3aaa2ec5ca6Eric Fischer account.name); 1433ee452ee5359cdfa3c3fbf6783722d3aaa2ec5ca6Eric Fischer final int index = titleAndSubtitle.indexOf('\n'); 143485e7279d9cc1ee8e4dd1f993a9e61a9eb547ecbcCostin Manolache String title = titleAndSubtitle; 143585e7279d9cc1ee8e4dd1f993a9e61a9eb547ecbcCostin Manolache String subtitle = ""; 143685e7279d9cc1ee8e4dd1f993a9e61a9eb547ecbcCostin Manolache if (index > 0) { 143785e7279d9cc1ee8e4dd1f993a9e61a9eb547ecbcCostin Manolache title = titleAndSubtitle.substring(0, index); 1438a12fccf57d5ec289793699d9b22ff45daccd3933Maggie Benthall subtitle = titleAndSubtitle.substring(index + 1); 143985e7279d9cc1ee8e4dd1f993a9e61a9eb547ecbcCostin Manolache } 144050cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn UserHandle user = new UserHandle(userId); 14414120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn n.setLatestEventInfo(mContext, title, subtitle, 14424120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn PendingIntent.getActivityAsUser(mContext, 0, intent, 144350cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn PendingIntent.FLAG_CANCEL_CURRENT, null, user)); 144450cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn installNotification(getCredentialPermissionNotificationId( 144550cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn account, authTokenType, uid), n, user); 1446d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1447d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 14485f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache private Intent newGrantCredentialsPermissionIntent(Account account, int uid, 14495f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache AccountAuthenticatorResponse response, String authTokenType, String authTokenLabel) { 1450d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 1451d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Intent intent = new Intent(mContext, GrantCredentialsPermissionActivity.class); 145246703b099516c383a6882815bcf9cd4df0ec538dBrian Carlstrom // See FLAG_ACTIVITY_NEW_TASK docs for limitations and benefits of the flag. 14539ec17366c17efd14c643ee88fa1132ab05197349Costin Manolache // Since it was set in Eclair+ we can't change it without breaking apps using 14549ec17366c17efd14c643ee88fa1132ab05197349Costin Manolache // the intent from a non-Activity context. 14559ec17366c17efd14c643ee88fa1132ab05197349Costin Manolache intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 1456d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana intent.addCategory( 1457d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana String.valueOf(getCredentialPermissionNotificationId(account, authTokenType, uid))); 14585f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache 1459d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana intent.putExtra(GrantCredentialsPermissionActivity.EXTRAS_ACCOUNT, account); 1460d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana intent.putExtra(GrantCredentialsPermissionActivity.EXTRAS_AUTH_TOKEN_TYPE, authTokenType); 1461d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana intent.putExtra(GrantCredentialsPermissionActivity.EXTRAS_RESPONSE, response); 1462d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana intent.putExtra(GrantCredentialsPermissionActivity.EXTRAS_REQUESTING_UID, uid); 14635f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache 1464d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana return intent; 1465d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1466d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 1467d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private Integer getCredentialPermissionNotificationId(Account account, String authTokenType, 1468d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana int uid) { 1469d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Integer id; 1470f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackborn UserAccounts accounts = getUserAccounts(UserHandle.getUserId(uid)); 147104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.credentialsPermissionNotificationIds) { 1472d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana final Pair<Pair<Account, String>, Integer> key = 1473d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana new Pair<Pair<Account, String>, Integer>( 1474d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana new Pair<Account, String>(account, authTokenType), uid); 147504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani id = accounts.credentialsPermissionNotificationIds.get(key); 1476d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (id == null) { 1477d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana id = mNotificationIds.incrementAndGet(); 147804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.credentialsPermissionNotificationIds.put(key, id); 1479d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1480d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1481d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana return id; 1482d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1483d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 148404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private Integer getSigninRequiredNotificationId(UserAccounts accounts, Account account) { 1485d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Integer id; 148604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.signinRequiredNotificationIds) { 148704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani id = accounts.signinRequiredNotificationIds.get(account); 1488d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (id == null) { 1489d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana id = mNotificationIds.incrementAndGet(); 149004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.signinRequiredNotificationIds.put(account, id); 1491d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1492d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1493d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana return id; 1494d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1495d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 149609e7e0ef8bcd8b7b78b79fb570de2032871f0c97Jatin Lodhia @Override 149727db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani public void addAccount(final IAccountManagerResponse response, final String accountType, 14983326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana final String authTokenType, final String[] requiredFeatures, 1499b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache final boolean expectActivityLaunch, final Bundle optionsIn) { 150056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 150156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "addAccount: accountType " + accountType 150256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", response " + response 150356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", authTokenType " + authTokenType 150456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", requiredFeatures " + stringArrayToString(requiredFeatures) 150556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", expectActivityLaunch " + expectActivityLaunch 150656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 150756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 150856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 1509382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (response == null) throw new IllegalArgumentException("response is null"); 1510382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (accountType == null) throw new IllegalArgumentException("accountType is null"); 1511d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkManageAccountsPermission(); 1512b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache 151371e6c697e54a43d357cc25d87a446d140f17396aAmith Yamasani // Is user disallowed from modifying accounts? 151427db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani if (!canUserModifyAccounts(Binder.getCallingUid())) { 1515df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani try { 1516df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani response.onError(AccountManager.ERROR_CODE_USER_RESTRICTED, 1517df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani "User is not allowed to add an account!"); 1518df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani } catch (RemoteException re) { 1519df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani } 152023c8b96a7e5c3f4c169bf65ae3886357943bb7b0Amith Yamasani Intent cantAddAccount = new Intent(mContext, CantAddAccountActivity.class); 152123c8b96a7e5c3f4c169bf65ae3886357943bb7b0Amith Yamasani cantAddAccount.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 152223c8b96a7e5c3f4c169bf65ae3886357943bb7b0Amith Yamasani long identityToken = clearCallingIdentity(); 152323c8b96a7e5c3f4c169bf65ae3886357943bb7b0Amith Yamasani try { 152423c8b96a7e5c3f4c169bf65ae3886357943bb7b0Amith Yamasani mContext.startActivityAsUser(cantAddAccount, UserHandle.CURRENT); 152523c8b96a7e5c3f4c169bf65ae3886357943bb7b0Amith Yamasani } finally { 152623c8b96a7e5c3f4c169bf65ae3886357943bb7b0Amith Yamasani restoreCallingIdentity(identityToken); 152723c8b96a7e5c3f4c169bf65ae3886357943bb7b0Amith Yamasani } 1528df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani return; 1529df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani } 1530df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani 153104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 1532b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache final int pid = Binder.getCallingPid(); 1533b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache final int uid = Binder.getCallingUid(); 1534b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache final Bundle options = (optionsIn == null) ? new Bundle() : optionsIn; 1535b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache options.putInt(AccountManager.KEY_CALLER_UID, uid); 1536b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache options.putInt(AccountManager.KEY_CALLER_PID, pid); 1537b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache 153826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 153926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 154004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani new Session(accounts, response, accountType, expectActivityLaunch, 15418570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana true /* stripAuthTokenFromResult */) { 15425bab9daf3cf66f4de19f8757e386030e8bef23ceCarlos Valdivia @Override 154326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana public void run() throws RemoteException { 15443348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache mAuthenticator.addAccount(this, mAccountType, authTokenType, requiredFeatures, 15453326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana options); 154626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1547a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 15485bab9daf3cf66f4de19f8757e386030e8bef23ceCarlos Valdivia @Override 154926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana protected String toDebugString(long now) { 155026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana return super.toDebugString(now) + ", addAccount" 15513326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + ", accountType " + accountType 15523326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + ", requiredFeatures " 15533326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + (requiredFeatures != null 15543326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana ? TextUtils.join(",", requiredFeatures) 15553326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana : null); 155626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 155726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana }.bind(); 155826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 155926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 156026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1561603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1562603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 15632c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani @Override 15642c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani public void confirmCredentialsAsUser(IAccountManagerResponse response, 15652c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani final Account account, final Bundle options, final boolean expectActivityLaunch, 15662c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani int userId) { 15672c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani // Only allow the system process to read accounts of other users 15682c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani if (userId != UserHandle.getCallingUserId() 1569bb49e8573e22cb6325dc31bf007a500fb7c136ebAmith Yamasani && Binder.getCallingUid() != Process.myUid() 1570464f530978b0b2517295fe3ade1dfa562a07487bJim Miller && mContext.checkCallingOrSelfPermission( 1571464f530978b0b2517295fe3ade1dfa562a07487bJim Miller android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 1572464f530978b0b2517295fe3ade1dfa562a07487bJim Miller != PackageManager.PERMISSION_GRANTED) { 15732c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani throw new SecurityException("User " + UserHandle.getCallingUserId() 15742c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani + " trying to confirm account credentials for " + userId); 15752c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani } 15762c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani 157756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 157856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "confirmCredentials: " + account 157956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", response " + response 158056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", expectActivityLaunch " + expectActivityLaunch 158156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 158256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 158356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 1584382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (response == null) throw new IllegalArgumentException("response is null"); 1585382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 1586d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkManageAccountsPermission(); 15872c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani UserAccounts accounts = getUserAccounts(userId); 158826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 158926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 159004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani new Session(accounts, response, account.type, expectActivityLaunch, 15918570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana true /* stripAuthTokenFromResult */) { 15925bab9daf3cf66f4de19f8757e386030e8bef23ceCarlos Valdivia @Override 159326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana public void run() throws RemoteException { 1594f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana mAuthenticator.confirmCredentials(this, account, options); 159526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 15965bab9daf3cf66f4de19f8757e386030e8bef23ceCarlos Valdivia @Override 159726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana protected String toDebugString(long now) { 159826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana return super.toDebugString(now) + ", confirmCredentials" 159926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana + ", " + account; 160026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 160126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana }.bind(); 160226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 160326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 160426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1605603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1606603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 160709e7e0ef8bcd8b7b78b79fb570de2032871f0c97Jatin Lodhia @Override 1608a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void updateCredentials(IAccountManagerResponse response, final Account account, 1609a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana final String authTokenType, final boolean expectActivityLaunch, 1610a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana final Bundle loginOptions) { 161156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 161256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "updateCredentials: " + account 161356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", response " + response 161456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", authTokenType " + authTokenType 161556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", expectActivityLaunch " + expectActivityLaunch 161656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 161756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 161856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 1619382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (response == null) throw new IllegalArgumentException("response is null"); 1620382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 1621382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null"); 1622d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkManageAccountsPermission(); 162304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 162426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 162526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 162604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani new Session(accounts, response, account.type, expectActivityLaunch, 16278570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana true /* stripAuthTokenFromResult */) { 16285bab9daf3cf66f4de19f8757e386030e8bef23ceCarlos Valdivia @Override 162926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana public void run() throws RemoteException { 163026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana mAuthenticator.updateCredentials(this, account, authTokenType, loginOptions); 163126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 16325bab9daf3cf66f4de19f8757e386030e8bef23ceCarlos Valdivia @Override 163326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana protected String toDebugString(long now) { 163426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana if (loginOptions != null) loginOptions.keySet(); 163526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana return super.toDebugString(now) + ", updateCredentials" 163626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana + ", " + account 163726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana + ", authTokenType " + authTokenType 163826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana + ", loginOptions " + loginOptions; 163926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 164026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana }.bind(); 164126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 164226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 164326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1644603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1645603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 164609e7e0ef8bcd8b7b78b79fb570de2032871f0c97Jatin Lodhia @Override 1647a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void editProperties(IAccountManagerResponse response, final String accountType, 1648a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana final boolean expectActivityLaunch) { 164956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 165056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "editProperties: accountType " + accountType 165156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", response " + response 165256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", expectActivityLaunch " + expectActivityLaunch 165356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 165456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 165556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 1656382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (response == null) throw new IllegalArgumentException("response is null"); 1657382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (accountType == null) throw new IllegalArgumentException("accountType is null"); 1658d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkManageAccountsPermission(); 165904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 166026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 166126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 166204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani new Session(accounts, response, accountType, expectActivityLaunch, 16638570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana true /* stripAuthTokenFromResult */) { 16645bab9daf3cf66f4de19f8757e386030e8bef23ceCarlos Valdivia @Override 166526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana public void run() throws RemoteException { 166626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana mAuthenticator.editProperties(this, mAccountType); 166726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 16685bab9daf3cf66f4de19f8757e386030e8bef23ceCarlos Valdivia @Override 166926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana protected String toDebugString(long now) { 167026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana return super.toDebugString(now) + ", editProperties" 167126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana + ", accountType " + accountType; 167226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 167326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana }.bind(); 167426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 167526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 167626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1677603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1678603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 16793326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana private class GetAccountsByTypeAndFeatureSession extends Session { 16803326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana private final String[] mFeatures; 16813326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana private volatile Account[] mAccountsOfType = null; 16823326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana private volatile ArrayList<Account> mAccountsWithFeatures = null; 16833326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana private volatile int mCurrentAccount = 0; 168409e7e0ef8bcd8b7b78b79fb570de2032871f0c97Jatin Lodhia private final int mCallingUid; 16853326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 168604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani public GetAccountsByTypeAndFeatureSession(UserAccounts accounts, 1687df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani IAccountManagerResponse response, String type, String[] features, int callingUid) { 168804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani super(accounts, response, type, false /* expectActivityLaunch */, 16898570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana true /* stripAuthTokenFromResult */); 1690df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani mCallingUid = callingUid; 16913326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana mFeatures = features; 16923326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 16933326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 16945bab9daf3cf66f4de19f8757e386030e8bef23ceCarlos Valdivia @Override 16953326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana public void run() throws RemoteException { 169604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (mAccounts.cacheLock) { 169727db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani mAccountsOfType = getAccountsFromCacheLocked(mAccounts, mAccountType, mCallingUid, 169827db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani null); 1699f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 17003326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana // check whether each account matches the requested features 17013326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana mAccountsWithFeatures = new ArrayList<Account>(mAccountsOfType.length); 17023326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana mCurrentAccount = 0; 17033326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 17043326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana checkAccount(); 17053326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 17063326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 17073326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana public void checkAccount() { 17083326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana if (mCurrentAccount >= mAccountsOfType.length) { 17093326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana sendResult(); 17103326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana return; 17113326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 17123326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 171329e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana final IAccountAuthenticator accountAuthenticator = mAuthenticator; 171429e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana if (accountAuthenticator == null) { 171529e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana // It is possible that the authenticator has died, which is indicated by 171629e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana // mAuthenticator being set to null. If this happens then just abort. 171729e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana // There is no need to send back a result or error in this case since 171829e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana // that already happened when mAuthenticator was cleared. 171929e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 172029e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana Log.v(TAG, "checkAccount: aborting session since we are no longer" 172129e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana + " connected to the authenticator, " + toDebugString()); 172229e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana } 172329e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana return; 172429e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana } 17253326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana try { 172629e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana accountAuthenticator.hasFeatures(this, mAccountsOfType[mCurrentAccount], mFeatures); 17273326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } catch (RemoteException e) { 1728f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana onError(AccountManager.ERROR_CODE_REMOTE_EXCEPTION, "remote exception"); 1729a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1730603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1731603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 17325bab9daf3cf66f4de19f8757e386030e8bef23ceCarlos Valdivia @Override 17333326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana public void onResult(Bundle result) { 17343326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana mNumResults++; 17353326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana if (result == null) { 1736f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana onError(AccountManager.ERROR_CODE_INVALID_RESPONSE, "null bundle"); 17373326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana return; 17383326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 1739f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana if (result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT, false)) { 17403326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana mAccountsWithFeatures.add(mAccountsOfType[mCurrentAccount]); 17413326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 17423326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana mCurrentAccount++; 17433326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana checkAccount(); 1744a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 17453326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 17463326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana public void sendResult() { 17473326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana IAccountManagerResponse response = getResponseAndClose(); 17483326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana if (response != null) { 17493326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana try { 17503326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana Account[] accounts = new Account[mAccountsWithFeatures.size()]; 17513326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana for (int i = 0; i < accounts.length; i++) { 17523326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana accounts[i] = mAccountsWithFeatures.get(i); 17533326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 175456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 175556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, getClass().getSimpleName() + " calling onResult() on response " 175656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + response); 175756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 17583326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana Bundle result = new Bundle(); 1759f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana result.putParcelableArray(AccountManager.KEY_ACCOUNTS, accounts); 17603326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana response.onResult(result); 17613326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } catch (RemoteException e) { 17623326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana // if the caller is dead then there is no one to care about remote exceptions 17633326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 17643326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana Log.v(TAG, "failure while notifying response", e); 17653326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 17663326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 17673326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 17683326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 17693326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 17703326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 17715bab9daf3cf66f4de19f8757e386030e8bef23ceCarlos Valdivia @Override 17723326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana protected String toDebugString(long now) { 17733326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana return super.toDebugString(now) + ", getAccountsByTypeAndFeatures" 17743326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + ", " + (mFeatures != null ? TextUtils.join(",", mFeatures) : null); 17753326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 17763326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 1777ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 177804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani /** 177904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani * Returns the accounts for a specific user 178004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani * @hide 178104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani */ 178204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani public Account[] getAccounts(int userId) { 178304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani checkReadAccountsPermission(); 178404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccounts(userId); 1785df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani int callingUid = Binder.getCallingUid(); 178604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani long identityToken = clearCallingIdentity(); 178704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani try { 178804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 178927db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani return getAccountsFromCacheLocked(accounts, null, callingUid, null); 179004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 179104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } finally { 179204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani restoreCallingIdentity(identityToken); 179304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 179404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 179504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani 1796f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani /** 17976ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey * Returns accounts for all running users. 17986ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey * 1799f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani * @hide 1800f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani */ 18016ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey public AccountAndUser[] getRunningAccounts() { 18026ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey final int[] runningUserIds; 18036ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey try { 18046ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey runningUserIds = ActivityManagerNative.getDefault().getRunningUserIds(); 18056ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey } catch (RemoteException e) { 18066ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey // Running in system_server; should never happen 18076ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey throw new RuntimeException(e); 18086ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey } 18096eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey return getAccounts(runningUserIds); 18106eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey } 18116eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey 18126eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey /** {@hide} */ 18136eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey public AccountAndUser[] getAllAccounts() { 18146eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey final List<UserInfo> users = getUserManager().getUsers(); 18156eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey final int[] userIds = new int[users.size()]; 18166eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey for (int i = 0; i < userIds.length; i++) { 18176eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey userIds[i] = users.get(i).id; 18186eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey } 18196eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey return getAccounts(userIds); 18206eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey } 18216ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey 18226eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey private AccountAndUser[] getAccounts(int[] userIds) { 18236ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey final ArrayList<AccountAndUser> runningAccounts = Lists.newArrayList(); 18240c19bf524493f2feedf442d390c878fd1ca66d7bAmith Yamasani for (int userId : userIds) { 18250c19bf524493f2feedf442d390c878fd1ca66d7bAmith Yamasani UserAccounts userAccounts = getUserAccounts(userId); 18260c19bf524493f2feedf442d390c878fd1ca66d7bAmith Yamasani if (userAccounts == null) continue; 18270c19bf524493f2feedf442d390c878fd1ca66d7bAmith Yamasani synchronized (userAccounts.cacheLock) { 18280c19bf524493f2feedf442d390c878fd1ca66d7bAmith Yamasani Account[] accounts = getAccountsFromCacheLocked(userAccounts, null, 18290c19bf524493f2feedf442d390c878fd1ca66d7bAmith Yamasani Binder.getCallingUid(), null); 18300c19bf524493f2feedf442d390c878fd1ca66d7bAmith Yamasani for (int a = 0; a < accounts.length; a++) { 18310c19bf524493f2feedf442d390c878fd1ca66d7bAmith Yamasani runningAccounts.add(new AccountAndUser(accounts[a], userId)); 1832f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani } 1833f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani } 1834f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani } 18356ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey 18366ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey AccountAndUser[] accountsArray = new AccountAndUser[runningAccounts.size()]; 18376ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey return runningAccounts.toArray(accountsArray); 1838f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani } 1839f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani 18402c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani @Override 18412c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani public Account[] getAccountsAsUser(String type, int userId) { 184227db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani return getAccountsAsUser(type, userId, null, -1); 184327db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani } 184427db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani 184527db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani private Account[] getAccountsAsUser(String type, int userId, String callingPackage, 184627db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani int packageUid) { 184727db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani int callingUid = Binder.getCallingUid(); 18482c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani // Only allow the system process to read accounts of other users 18492c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani if (userId != UserHandle.getCallingUserId() 1850bb49e8573e22cb6325dc31bf007a500fb7c136ebAmith Yamasani && callingUid != Process.myUid() 1851464f530978b0b2517295fe3ade1dfa562a07487bJim Miller && mContext.checkCallingOrSelfPermission( 1852464f530978b0b2517295fe3ade1dfa562a07487bJim Miller android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 1853464f530978b0b2517295fe3ade1dfa562a07487bJim Miller != PackageManager.PERMISSION_GRANTED) { 18542c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani throw new SecurityException("User " + UserHandle.getCallingUserId() 18552c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani + " trying to get account for " + userId); 18562c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani } 18572c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani 185856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 185956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "getAccounts: accountType " + type 186056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 186156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 186256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 186327db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani // If the original calling app was using the framework account chooser activity, we'll 186427db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani // be passed in the original caller's uid here, which is what should be used for filtering. 186527db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani if (packageUid != -1 && UserHandle.isSameApp(callingUid, Process.myUid())) { 186627db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani callingUid = packageUid; 186727db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani } 1868ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana checkReadAccountsPermission(); 18692c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani UserAccounts accounts = getUserAccounts(userId); 1870ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana long identityToken = clearCallingIdentity(); 1871ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana try { 187204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 187327db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani return getAccountsFromCacheLocked(accounts, type, callingUid, callingPackage); 1874f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 1875ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } finally { 1876ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana restoreCallingIdentity(identityToken); 1877ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 1878ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 1879ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 18802c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani @Override 188167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani public boolean addSharedAccountAsUser(Account account, int userId) { 188267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani userId = handleIncomingUser(userId); 188367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani SQLiteDatabase db = getUserAccounts(userId).openHelper.getWritableDatabase(); 188467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani ContentValues values = new ContentValues(); 188567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani values.put(ACCOUNTS_NAME, account.name); 188667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani values.put(ACCOUNTS_TYPE, account.type); 188767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani db.delete(TABLE_SHARED_ACCOUNTS, ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?", 188867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani new String[] {account.name, account.type}); 188967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani long accountId = db.insert(TABLE_SHARED_ACCOUNTS, ACCOUNTS_NAME, values); 189067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani if (accountId < 0) { 189167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani Log.w(TAG, "insertAccountIntoDatabase: " + account 189267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani + ", skipping the DB insert failed"); 189367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani return false; 189467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 189567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani return true; 189667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 189767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani 189867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani @Override 189967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani public boolean removeSharedAccountAsUser(Account account, int userId) { 190067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani userId = handleIncomingUser(userId); 190167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani UserAccounts accounts = getUserAccounts(userId); 190267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani SQLiteDatabase db = accounts.openHelper.getWritableDatabase(); 190367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani int r = db.delete(TABLE_SHARED_ACCOUNTS, ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?", 190467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani new String[] {account.name, account.type}); 190567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani if (r > 0) { 190667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani removeAccountInternal(accounts, account); 190767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 190867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani return r > 0; 190967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 191067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani 191167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani @Override 191267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani public Account[] getSharedAccountsAsUser(int userId) { 191367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani userId = handleIncomingUser(userId); 191467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani UserAccounts accounts = getUserAccounts(userId); 191567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani ArrayList<Account> accountList = new ArrayList<Account>(); 191667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani Cursor cursor = null; 191767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani try { 191867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani cursor = accounts.openHelper.getReadableDatabase() 191967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani .query(TABLE_SHARED_ACCOUNTS, new String[]{ACCOUNTS_NAME, ACCOUNTS_TYPE}, 192067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani null, null, null, null, null); 192167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani if (cursor != null && cursor.moveToFirst()) { 192267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani int nameIndex = cursor.getColumnIndex(ACCOUNTS_NAME); 192367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani int typeIndex = cursor.getColumnIndex(ACCOUNTS_TYPE); 192467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani do { 192567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani accountList.add(new Account(cursor.getString(nameIndex), 192667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani cursor.getString(typeIndex))); 192767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } while (cursor.moveToNext()); 192867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 192967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } finally { 193067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani if (cursor != null) { 193167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani cursor.close(); 193267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 193367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 193467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani Account[] accountArray = new Account[accountList.size()]; 193567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani accountList.toArray(accountArray); 193667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani return accountArray; 193767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 193867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani 193967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani @Override 19402c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani public Account[] getAccounts(String type) { 19412c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani return getAccountsAsUser(type, UserHandle.getCallingUserId()); 19422c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani } 19432c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani 194427db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani @Override 194527db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani public Account[] getAccountsForPackage(String packageName, int uid) { 194627db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani int callingUid = Binder.getCallingUid(); 194727db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani if (!UserHandle.isSameApp(callingUid, Process.myUid())) { 194827db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani throw new SecurityException("getAccountsForPackage() called from unauthorized uid " 194927db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani + callingUid + " with uid=" + uid); 195027db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani } 195127db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani return getAccountsAsUser(null, UserHandle.getCallingUserId(), packageName, uid); 195227db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani } 195327db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani 19543b458ad9ee5f2d6b7cf28a13bc29123cdf540763Amith Yamasani @Override 19553b458ad9ee5f2d6b7cf28a13bc29123cdf540763Amith Yamasani public Account[] getAccountsByTypeForPackage(String type, String packageName) { 19563b458ad9ee5f2d6b7cf28a13bc29123cdf540763Amith Yamasani checkBinderPermission(android.Manifest.permission.INTERACT_ACROSS_USERS); 19573b458ad9ee5f2d6b7cf28a13bc29123cdf540763Amith Yamasani int packageUid = -1; 19583b458ad9ee5f2d6b7cf28a13bc29123cdf540763Amith Yamasani try { 19593b458ad9ee5f2d6b7cf28a13bc29123cdf540763Amith Yamasani packageUid = AppGlobals.getPackageManager().getPackageUid( 19603b458ad9ee5f2d6b7cf28a13bc29123cdf540763Amith Yamasani packageName, UserHandle.getCallingUserId()); 19613b458ad9ee5f2d6b7cf28a13bc29123cdf540763Amith Yamasani } catch (RemoteException re) { 19623b458ad9ee5f2d6b7cf28a13bc29123cdf540763Amith Yamasani Slog.e(TAG, "Couldn't determine the packageUid for " + packageName + re); 19633b458ad9ee5f2d6b7cf28a13bc29123cdf540763Amith Yamasani return new Account[0]; 19643b458ad9ee5f2d6b7cf28a13bc29123cdf540763Amith Yamasani } 19653b458ad9ee5f2d6b7cf28a13bc29123cdf540763Amith Yamasani return getAccountsAsUser(type, UserHandle.getCallingUserId(), packageName, packageUid); 19663b458ad9ee5f2d6b7cf28a13bc29123cdf540763Amith Yamasani } 19673b458ad9ee5f2d6b7cf28a13bc29123cdf540763Amith Yamasani 196809e7e0ef8bcd8b7b78b79fb570de2032871f0c97Jatin Lodhia @Override 1969ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana public void getAccountsByFeatures(IAccountManagerResponse response, 19703326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana String type, String[] features) { 197156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 197256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "getAccounts: accountType " + type 197356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", response " + response 197456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", features " + stringArrayToString(features) 197556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 197656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 197756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 1978382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (response == null) throw new IllegalArgumentException("response is null"); 1979382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (type == null) throw new IllegalArgumentException("accountType is null"); 1980d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkReadAccountsPermission(); 198104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts userAccounts = getUserAccountsForCaller(); 1982df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani int callingUid = Binder.getCallingUid(); 19833326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana long identityToken = clearCallingIdentity(); 19843326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana try { 1985ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana if (features == null || features.length == 0) { 1986f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana Account[] accounts; 198704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (userAccounts.cacheLock) { 198827db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani accounts = getAccountsFromCacheLocked(userAccounts, type, callingUid, null); 1989f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 1990d4a9d6c42bb412e27a8383aaacd051419d98a662Fred Quintana Bundle result = new Bundle(); 1991d4a9d6c42bb412e27a8383aaacd051419d98a662Fred Quintana result.putParcelableArray(AccountManager.KEY_ACCOUNTS, accounts); 1992d4a9d6c42bb412e27a8383aaacd051419d98a662Fred Quintana onResult(response, result); 1993ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana return; 1994ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 1995df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani new GetAccountsByTypeAndFeatureSession(userAccounts, response, type, features, 1996df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani callingUid).bind(); 19973326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } finally { 19983326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana restoreCallingIdentity(identityToken); 19993326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 20003326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 20013326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 2002f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana private long getAccountIdLocked(SQLiteDatabase db, Account account) { 2003603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana Cursor cursor = db.query(TABLE_ACCOUNTS, new String[]{ACCOUNTS_ID}, 2004ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana "name=? AND type=?", new String[]{account.name, account.type}, null, null, null); 2005603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana try { 2006603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana if (cursor.moveToNext()) { 2007603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana return cursor.getLong(0); 2008603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2009603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana return -1; 2010603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } finally { 2011603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana cursor.close(); 2012603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2013603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2014603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 2015f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana private long getExtrasIdLocked(SQLiteDatabase db, long accountId, String key) { 2016603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana Cursor cursor = db.query(TABLE_EXTRAS, new String[]{EXTRAS_ID}, 2017603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana EXTRAS_ACCOUNTS_ID + "=" + accountId + " AND " + EXTRAS_KEY + "=?", 2018603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana new String[]{key}, null, null, null); 2019603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana try { 2020603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana if (cursor.moveToNext()) { 2021603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana return cursor.getLong(0); 2022603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2023603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana return -1; 2024603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } finally { 2025603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana cursor.close(); 2026603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2027603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2028603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 2029a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana private abstract class Session extends IAccountAuthenticatorResponse.Stub 2030b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana implements IBinder.DeathRecipient, ServiceConnection { 2031603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana IAccountManagerResponse mResponse; 2032603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana final String mAccountType; 2033a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana final boolean mExpectActivityLaunch; 2034a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana final long mCreationTime; 2035a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 20363326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana public int mNumResults = 0; 2037a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana private int mNumRequestContinued = 0; 2038a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana private int mNumErrors = 0; 2039a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 2040603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana IAccountAuthenticator mAuthenticator = null; 2041603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 20428570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana private final boolean mStripAuthTokenFromResult; 204304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani protected final UserAccounts mAccounts; 20448570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana 204504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani public Session(UserAccounts accounts, IAccountManagerResponse response, String accountType, 20468570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana boolean expectActivityLaunch, boolean stripAuthTokenFromResult) { 2047603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana super(); 204867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani //if (response == null) throw new IllegalArgumentException("response is null"); 20493326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana if (accountType == null) throw new IllegalArgumentException("accountType is null"); 205004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani mAccounts = accounts; 20518570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana mStripAuthTokenFromResult = stripAuthTokenFromResult; 2052603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mResponse = response; 2053603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mAccountType = accountType; 2054a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana mExpectActivityLaunch = expectActivityLaunch; 2055a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana mCreationTime = SystemClock.elapsedRealtime(); 2056a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana synchronized (mSessions) { 2057a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana mSessions.put(toString(), this); 2058a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 205967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani if (response != null) { 206067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani try { 206167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani response.asBinder().linkToDeath(this, 0 /* flags */); 206267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } catch (RemoteException e) { 206367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani mResponse = null; 206467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani binderDied(); 206567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 2066a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 2067603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2068603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 2069a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana IAccountManagerResponse getResponseAndClose() { 2070603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana if (mResponse == null) { 2071603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana // this session has already been closed 2072603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana return null; 2073603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2074a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana IAccountManagerResponse response = mResponse; 2075a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana close(); // this clears mResponse so we need to save the response before this call 2076a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana return response; 2077a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 2078a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 2079a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana private void close() { 2080a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana synchronized (mSessions) { 2081a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (mSessions.remove(toString()) == null) { 2082a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana // the session was already closed, so bail out now 2083a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana return; 2084a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 2085a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 2086a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (mResponse != null) { 2087a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana // stop listening for response deaths 2088a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana mResponse.asBinder().unlinkToDeath(this, 0 /* flags */); 2089a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 2090a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana // clear this so that we don't accidentally send any further results 2091a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana mResponse = null; 2092a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 2093603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana cancelTimeout(); 2094603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana unbind(); 2095a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 2096a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 209709e7e0ef8bcd8b7b78b79fb570de2032871f0c97Jatin Lodhia @Override 2098a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void binderDied() { 2099603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mResponse = null; 2100a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana close(); 2101a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 2102a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 2103a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana protected String toDebugString() { 2104a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana return toDebugString(SystemClock.elapsedRealtime()); 2105a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 2106a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 2107a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana protected String toDebugString(long now) { 2108a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana return "Session: expectLaunch " + mExpectActivityLaunch 2109a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + ", connected " + (mAuthenticator != null) 2110a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + ", stats (" + mNumResults + "/" + mNumRequestContinued 2111a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + "/" + mNumErrors + ")" 2112a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + ", lifetime " + ((now - mCreationTime) / 1000.0); 2113603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2114603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 2115603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana void bind() { 2116a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 2117a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana Log.v(TAG, "initiating bind to authenticator type " + mAccountType); 2118a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 2119b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana if (!bindToAuthenticator(mAccountType)) { 2120a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana Log.d(TAG, "bind attempt failed for " + toDebugString()); 2121f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana onError(AccountManager.ERROR_CODE_REMOTE_EXCEPTION, "bind failure"); 2122603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2123603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2124603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 2125603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private void unbind() { 2126603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana if (mAuthenticator != null) { 2127603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mAuthenticator = null; 2128b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana mContext.unbindService(this); 2129603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2130603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2131603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 2132603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public void scheduleTimeout() { 2133603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mMessageHandler.sendMessageDelayed( 2134603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mMessageHandler.obtainMessage(MESSAGE_TIMED_OUT, this), TIMEOUT_DELAY_MS); 2135603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2136603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 2137603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public void cancelTimeout() { 2138603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mMessageHandler.removeMessages(MESSAGE_TIMED_OUT, this); 2139603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2140603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 214109e7e0ef8bcd8b7b78b79fb570de2032871f0c97Jatin Lodhia @Override 2142b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana public void onServiceConnected(ComponentName name, IBinder service) { 2143603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mAuthenticator = IAccountAuthenticator.Stub.asInterface(service); 2144a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana try { 2145a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana run(); 2146a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } catch (RemoteException e) { 2147f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana onError(AccountManager.ERROR_CODE_REMOTE_EXCEPTION, 2148a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana "remote exception"); 2149a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 2150603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2151603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 215209e7e0ef8bcd8b7b78b79fb570de2032871f0c97Jatin Lodhia @Override 2153b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana public void onServiceDisconnected(ComponentName name) { 2154a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana mAuthenticator = null; 2155a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana IAccountManagerResponse response = getResponseAndClose(); 2156603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana if (response != null) { 2157166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana try { 2158166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana response.onError(AccountManager.ERROR_CODE_REMOTE_EXCEPTION, 2159166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana "disconnected"); 2160166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana } catch (RemoteException e) { 2161166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 2162166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana Log.v(TAG, "Session.onServiceDisconnected: " 2163166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana + "caught RemoteException while responding", e); 2164166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana } 2165166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana } 2166603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2167603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2168603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 2169b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana public abstract void run() throws RemoteException; 2170b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana 2171603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public void onTimedOut() { 2172a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana IAccountManagerResponse response = getResponseAndClose(); 2173603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana if (response != null) { 2174166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana try { 2175166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana response.onError(AccountManager.ERROR_CODE_REMOTE_EXCEPTION, 2176166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana "timeout"); 2177166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana } catch (RemoteException e) { 2178166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 2179166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana Log.v(TAG, "Session.onTimedOut: caught RemoteException while responding", 2180166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana e); 2181166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana } 2182166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana } 2183603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2184603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2185603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 21865bab9daf3cf66f4de19f8757e386030e8bef23ceCarlos Valdivia @Override 2187a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void onResult(Bundle result) { 2188a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana mNumResults++; 21895bab9daf3cf66f4de19f8757e386030e8bef23ceCarlos Valdivia Intent intent = null; 21905bab9daf3cf66f4de19f8757e386030e8bef23ceCarlos Valdivia if (result != null 21915bab9daf3cf66f4de19f8757e386030e8bef23ceCarlos Valdivia && (intent = result.getParcelable(AccountManager.KEY_INTENT)) != null) { 21925bab9daf3cf66f4de19f8757e386030e8bef23ceCarlos Valdivia /* 21935bab9daf3cf66f4de19f8757e386030e8bef23ceCarlos Valdivia * The Authenticator API allows third party authenticators to 21945bab9daf3cf66f4de19f8757e386030e8bef23ceCarlos Valdivia * supply arbitrary intents to other apps that they can run, 21955bab9daf3cf66f4de19f8757e386030e8bef23ceCarlos Valdivia * this can be very bad when those apps are in the system like 21965bab9daf3cf66f4de19f8757e386030e8bef23ceCarlos Valdivia * the System Settings. 21975bab9daf3cf66f4de19f8757e386030e8bef23ceCarlos Valdivia */ 21985bab9daf3cf66f4de19f8757e386030e8bef23ceCarlos Valdivia int authenticatorUid = Binder.getCallingUid(); 2199416747aea11351c4327ac74c3a8d7bf338cde946Carlos Valdivia long bid = Binder.clearCallingIdentity(); 2200416747aea11351c4327ac74c3a8d7bf338cde946Carlos Valdivia try { 2201416747aea11351c4327ac74c3a8d7bf338cde946Carlos Valdivia PackageManager pm = mContext.getPackageManager(); 2202416747aea11351c4327ac74c3a8d7bf338cde946Carlos Valdivia ResolveInfo resolveInfo = pm.resolveActivityAsUser(intent, 0, mAccounts.userId); 2203416747aea11351c4327ac74c3a8d7bf338cde946Carlos Valdivia int targetUid = resolveInfo.activityInfo.applicationInfo.uid; 2204416747aea11351c4327ac74c3a8d7bf338cde946Carlos Valdivia if (PackageManager.SIGNATURE_MATCH != 2205416747aea11351c4327ac74c3a8d7bf338cde946Carlos Valdivia pm.checkSignatures(authenticatorUid, targetUid)) { 2206416747aea11351c4327ac74c3a8d7bf338cde946Carlos Valdivia throw new SecurityException( 2207416747aea11351c4327ac74c3a8d7bf338cde946Carlos Valdivia "Activity to be started with KEY_INTENT must " + 2208416747aea11351c4327ac74c3a8d7bf338cde946Carlos Valdivia "share Authenticator's signatures"); 2209416747aea11351c4327ac74c3a8d7bf338cde946Carlos Valdivia } 2210416747aea11351c4327ac74c3a8d7bf338cde946Carlos Valdivia } finally { 2211416747aea11351c4327ac74c3a8d7bf338cde946Carlos Valdivia Binder.restoreCallingIdentity(bid); 22125bab9daf3cf66f4de19f8757e386030e8bef23ceCarlos Valdivia } 22135bab9daf3cf66f4de19f8757e386030e8bef23ceCarlos Valdivia } 22145bab9daf3cf66f4de19f8757e386030e8bef23ceCarlos Valdivia if (result != null 22155bab9daf3cf66f4de19f8757e386030e8bef23ceCarlos Valdivia && !TextUtils.isEmpty(result.getString(AccountManager.KEY_AUTHTOKEN))) { 2216f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana String accountName = result.getString(AccountManager.KEY_ACCOUNT_NAME); 2217f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana String accountType = result.getString(AccountManager.KEY_ACCOUNT_TYPE); 2218d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (!TextUtils.isEmpty(accountName) && !TextUtils.isEmpty(accountType)) { 2219d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Account account = new Account(accountName, accountType); 222050cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn cancelNotification(getSigninRequiredNotificationId(mAccounts, account), 222150cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn new UserHandle(mAccounts.userId)); 2222d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2223603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2224a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana IAccountManagerResponse response; 2225a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (mExpectActivityLaunch && result != null 2226f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana && result.containsKey(AccountManager.KEY_INTENT)) { 2227a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana response = mResponse; 2228a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } else { 2229a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana response = getResponseAndClose(); 2230603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2231603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana if (response != null) { 2232603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana try { 2233a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (result == null) { 223456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 223556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, getClass().getSimpleName() 223656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + " calling onError() on response " + response); 223756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 2238f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana response.onError(AccountManager.ERROR_CODE_INVALID_RESPONSE, 2239a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana "null bundle returned"); 2240a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } else { 22418570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana if (mStripAuthTokenFromResult) { 22428570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana result.remove(AccountManager.KEY_AUTHTOKEN); 22438570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana } 224456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 224556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, getClass().getSimpleName() 224656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + " calling onResult() on response " + response); 224756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 224809e7e0ef8bcd8b7b78b79fb570de2032871f0c97Jatin Lodhia if ((result.getInt(AccountManager.KEY_ERROR_CODE, -1) > 0) && 224909e7e0ef8bcd8b7b78b79fb570de2032871f0c97Jatin Lodhia (intent == null)) { 225009e7e0ef8bcd8b7b78b79fb570de2032871f0c97Jatin Lodhia // All AccountManager error codes are greater than 0 225109e7e0ef8bcd8b7b78b79fb570de2032871f0c97Jatin Lodhia response.onError(result.getInt(AccountManager.KEY_ERROR_CODE), 225209e7e0ef8bcd8b7b78b79fb570de2032871f0c97Jatin Lodhia result.getString(AccountManager.KEY_ERROR_MESSAGE)); 225309e7e0ef8bcd8b7b78b79fb570de2032871f0c97Jatin Lodhia } else { 225409e7e0ef8bcd8b7b78b79fb570de2032871f0c97Jatin Lodhia response.onResult(result); 225509e7e0ef8bcd8b7b78b79fb570de2032871f0c97Jatin Lodhia } 2256a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 2257603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } catch (RemoteException e) { 2258a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana // if the caller is dead then there is no one to care about remote exceptions 2259a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 2260a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana Log.v(TAG, "failure while notifying response", e); 2261a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 2262603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2263603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2264603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2265603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 226609e7e0ef8bcd8b7b78b79fb570de2032871f0c97Jatin Lodhia @Override 2267a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void onRequestContinued() { 2268a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana mNumRequestContinued++; 2269603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2270603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 227109e7e0ef8bcd8b7b78b79fb570de2032871f0c97Jatin Lodhia @Override 2272603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public void onError(int errorCode, String errorMessage) { 2273a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana mNumErrors++; 2274a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana IAccountManagerResponse response = getResponseAndClose(); 2275a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (response != null) { 2276a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 227756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, getClass().getSimpleName() 227856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + " calling onError() on response " + response); 2279a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 2280a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana try { 2281a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana response.onError(errorCode, errorMessage); 2282a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } catch (RemoteException e) { 2283a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 2284a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana Log.v(TAG, "Session.onError: caught RemoteException while responding", e); 2285a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 2286a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 2287a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } else { 2288a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 2289a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana Log.v(TAG, "Session.onError: already closed"); 2290a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 2291603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2292603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2293b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana 2294b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana /** 2295b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana * find the component name for the authenticator and initiate a bind 2296b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana * if no authenticator or the bind fails then return false, otherwise return true 2297b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana */ 2298b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana private boolean bindToAuthenticator(String authenticatorType) { 22996ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey final AccountAuthenticatorCache.ServiceInfo<AuthenticatorDescription> authenticatorInfo; 23006ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey authenticatorInfo = mAuthenticatorCache.getServiceInfo( 23016ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey AuthenticatorDescription.newKey(authenticatorType), mAccounts.userId); 2302b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana if (authenticatorInfo == null) { 2303b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 2304b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana Log.v(TAG, "there is no authenticator for " + authenticatorType 2305b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana + ", bailing out"); 2306b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana } 2307b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana return false; 2308b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana } 2309b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana 2310b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana Intent intent = new Intent(); 2311b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana intent.setAction(AccountManager.ACTION_AUTHENTICATOR_INTENT); 2312b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana intent.setComponent(authenticatorInfo.componentName); 2313b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 2314b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana Log.v(TAG, "performing bindService to " + authenticatorInfo.componentName); 2315b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana } 231627b89e6658a0d233a53f5d7ca20dc57fec82d955Amith Yamasani if (!mContext.bindServiceAsUser(intent, this, Context.BIND_AUTO_CREATE, 231727b89e6658a0d233a53f5d7ca20dc57fec82d955Amith Yamasani new UserHandle(mAccounts.userId))) { 2318b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 2319b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana Log.v(TAG, "bindService to " + authenticatorInfo.componentName + " failed"); 2320b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana } 2321b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana return false; 2322b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana } 2323b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana 2324b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana 2325b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana return true; 2326b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana } 2327603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2328603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 2329603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private class MessageHandler extends Handler { 2330603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana MessageHandler(Looper looper) { 2331603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana super(looper); 2332603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 23333348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache 23345bab9daf3cf66f4de19f8757e386030e8bef23ceCarlos Valdivia @Override 2335603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public void handleMessage(Message msg) { 2336603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana switch (msg.what) { 2337603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana case MESSAGE_TIMED_OUT: 2338603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana Session session = (Session)msg.obj; 2339603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana session.onTimedOut(); 2340603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana break; 2341603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 23425be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani case MESSAGE_COPY_SHARED_ACCOUNT: 23435be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani copyAccountToUser((Account) msg.obj, msg.arg1, msg.arg2); 23445be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani break; 23455be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani 2346603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana default: 2347603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana throw new IllegalStateException("unhandled message: " + msg.what); 2348603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2349603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2350603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2351603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 235204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private static String getDatabaseName(int userId) { 235304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani File systemDir = Environment.getSystemSecureDirectory(); 235461f57379ca2c5b6290c8da7548fa17128f7ab24fAmith Yamasani File databaseFile = new File(Environment.getUserSystemDirectory(userId), DATABASE_NAME); 235504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani if (userId == 0) { 2356a23bb38628ac1f5dc4ebe6847faedc424dd5fce1Amith Yamasani // Migrate old file, if it exists, to the new location. 2357a23bb38628ac1f5dc4ebe6847faedc424dd5fce1Amith Yamasani // Make sure the new file doesn't already exist. A dummy file could have been 2358a23bb38628ac1f5dc4ebe6847faedc424dd5fce1Amith Yamasani // accidentally created in the old location, causing the new one to become corrupted 2359a23bb38628ac1f5dc4ebe6847faedc424dd5fce1Amith Yamasani // as well. 236004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani File oldFile = new File(systemDir, DATABASE_NAME); 2361a23bb38628ac1f5dc4ebe6847faedc424dd5fce1Amith Yamasani if (oldFile.exists() && !databaseFile.exists()) { 2362c6b0f99bb31405902b40a96f6491a9adcaaac169Marc Blank // Check for use directory; create if it doesn't exist, else renameTo will fail 236361f57379ca2c5b6290c8da7548fa17128f7ab24fAmith Yamasani File userDir = Environment.getUserSystemDirectory(userId); 2364c6b0f99bb31405902b40a96f6491a9adcaaac169Marc Blank if (!userDir.exists()) { 2365c6b0f99bb31405902b40a96f6491a9adcaaac169Marc Blank if (!userDir.mkdirs()) { 2366c6b0f99bb31405902b40a96f6491a9adcaaac169Marc Blank throw new IllegalStateException("User dir cannot be created: " + userDir); 2367c6b0f99bb31405902b40a96f6491a9adcaaac169Marc Blank } 2368c6b0f99bb31405902b40a96f6491a9adcaaac169Marc Blank } 2369c6b0f99bb31405902b40a96f6491a9adcaaac169Marc Blank if (!oldFile.renameTo(databaseFile)) { 2370c6b0f99bb31405902b40a96f6491a9adcaaac169Marc Blank throw new IllegalStateException("User dir cannot be migrated: " + databaseFile); 2371c6b0f99bb31405902b40a96f6491a9adcaaac169Marc Blank } 237204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 2373a8529f68671a8a118751cb6ad577f44eaf076b96Oscar Montemayor } 237404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani return databaseFile.getPath(); 2375a8529f68671a8a118751cb6ad577f44eaf076b96Oscar Montemayor } 2376a8529f68671a8a118751cb6ad577f44eaf076b96Oscar Montemayor 237704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani static class DatabaseHelper extends SQLiteOpenHelper { 2378a8529f68671a8a118751cb6ad577f44eaf076b96Oscar Montemayor 237904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani public DatabaseHelper(Context context, int userId) { 238004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani super(context, AccountManagerService.getDatabaseName(userId), null, DATABASE_VERSION); 2381603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2382603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 2383f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana /** 2384f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana * This call needs to be made while the mCacheLock is held. The way to 2385f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana * ensure this is to get the lock any time a method is called ont the DatabaseHelper 2386f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana * @param db The database. 2387f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana */ 2388603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana @Override 2389603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public void onCreate(SQLiteDatabase db) { 2390603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana db.execSQL("CREATE TABLE " + TABLE_ACCOUNTS + " ( " 2391603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + ACCOUNTS_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " 2392603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + ACCOUNTS_NAME + " TEXT NOT NULL, " 2393603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + ACCOUNTS_TYPE + " TEXT NOT NULL, " 2394603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + ACCOUNTS_PASSWORD + " TEXT, " 2395603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + "UNIQUE(" + ACCOUNTS_NAME + "," + ACCOUNTS_TYPE + "))"); 2396603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 2397603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana db.execSQL("CREATE TABLE " + TABLE_AUTHTOKENS + " ( " 2398603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + AUTHTOKENS_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " 2399603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + AUTHTOKENS_ACCOUNTS_ID + " INTEGER NOT NULL, " 2400603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + AUTHTOKENS_TYPE + " TEXT NOT NULL, " 2401603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + AUTHTOKENS_AUTHTOKEN + " TEXT, " 2402603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + "UNIQUE (" + AUTHTOKENS_ACCOUNTS_ID + "," + AUTHTOKENS_TYPE + "))"); 2403603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 2404d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana createGrantsTable(db); 2405d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 2406603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana db.execSQL("CREATE TABLE " + TABLE_EXTRAS + " ( " 2407603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + EXTRAS_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " 2408603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + EXTRAS_ACCOUNTS_ID + " INTEGER, " 2409603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + EXTRAS_KEY + " TEXT NOT NULL, " 2410603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + EXTRAS_VALUE + " TEXT, " 2411603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + "UNIQUE(" + EXTRAS_ACCOUNTS_ID + "," + EXTRAS_KEY + "))"); 2412603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 2413603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana db.execSQL("CREATE TABLE " + TABLE_META + " ( " 2414603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + META_KEY + " TEXT PRIMARY KEY NOT NULL, " 2415603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + META_VALUE + " TEXT)"); 2416a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 241767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani createSharedAccountsTable(db); 241867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani 2419d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana createAccountsDeletionTrigger(db); 2420d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2421d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 242267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani private void createSharedAccountsTable(SQLiteDatabase db) { 242367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani db.execSQL("CREATE TABLE " + TABLE_SHARED_ACCOUNTS + " ( " 242467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani + ACCOUNTS_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " 242567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani + ACCOUNTS_NAME + " TEXT NOT NULL, " 242667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani + ACCOUNTS_TYPE + " TEXT NOT NULL, " 242767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani + "UNIQUE(" + ACCOUNTS_NAME + "," + ACCOUNTS_TYPE + "))"); 242867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 242967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani 2430d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private void createAccountsDeletionTrigger(SQLiteDatabase db) { 2431a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana db.execSQL("" 2432a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + " CREATE TRIGGER " + TABLE_ACCOUNTS + "Delete DELETE ON " + TABLE_ACCOUNTS 2433a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + " BEGIN" 2434a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + " DELETE FROM " + TABLE_AUTHTOKENS 2435a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + " WHERE " + AUTHTOKENS_ACCOUNTS_ID + "=OLD." + ACCOUNTS_ID + " ;" 2436a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + " DELETE FROM " + TABLE_EXTRAS 2437a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + " WHERE " + EXTRAS_ACCOUNTS_ID + "=OLD." + ACCOUNTS_ID + " ;" 2438d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + " DELETE FROM " + TABLE_GRANTS 2439d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + " WHERE " + GRANTS_ACCOUNTS_ID + "=OLD." + ACCOUNTS_ID + " ;" 2440a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + " END"); 2441603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2442603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 2443d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private void createGrantsTable(SQLiteDatabase db) { 2444d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana db.execSQL("CREATE TABLE " + TABLE_GRANTS + " ( " 2445d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + GRANTS_ACCOUNTS_ID + " INTEGER NOT NULL, " 2446d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + GRANTS_AUTH_TOKEN_TYPE + " STRING NOT NULL, " 2447d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + GRANTS_GRANTEE_UID + " INTEGER NOT NULL, " 2448d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + "UNIQUE (" + GRANTS_ACCOUNTS_ID + "," + GRANTS_AUTH_TOKEN_TYPE 2449d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + "," + GRANTS_GRANTEE_UID + "))"); 2450d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2451d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 2452603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana @Override 2453603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 2454a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana Log.e(TAG, "upgrade from version " + oldVersion + " to version " + newVersion); 2455603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 2456a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (oldVersion == 1) { 2457d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana // no longer need to do anything since the work is done 2458d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana // when upgrading from version 2 2459d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana oldVersion++; 2460d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2461d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 2462d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (oldVersion == 2) { 2463d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana createGrantsTable(db); 2464d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana db.execSQL("DROP TRIGGER " + TABLE_ACCOUNTS + "Delete"); 2465d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana createAccountsDeletionTrigger(db); 2466a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana oldVersion++; 2467a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 24683348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache 24693348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache if (oldVersion == 3) { 24703348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache db.execSQL("UPDATE " + TABLE_ACCOUNTS + " SET " + ACCOUNTS_TYPE + 24713348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache " = 'com.google' WHERE " + ACCOUNTS_TYPE + " == 'com.google.GAIA'"); 24723348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache oldVersion++; 24733348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache } 247467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani 247567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani if (oldVersion == 4) { 247667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani createSharedAccountsTable(db); 247767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani oldVersion++; 247867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 247967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani 248067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani if (oldVersion != newVersion) { 248167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani Log.e(TAG, "failed to upgrade version " + oldVersion + " to version " + newVersion); 248267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 2483603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2484603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 2485603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana @Override 2486603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public void onOpen(SQLiteDatabase db) { 2487603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "opened database " + DATABASE_NAME); 2488603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2489603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2490603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 2491603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public IBinder onBind(Intent intent) { 2492603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana return asBinder(); 2493603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2494a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 24951cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks /** 24961cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks * Searches array of arguments for the specified string 24971cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks * @param args array of argument strings 24981cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks * @param value value to search for 24991cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks * @return true if the value is contained in the array 25001cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks */ 25011cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks private static boolean scanArgs(String[] args, String value) { 25021cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks if (args != null) { 25031cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks for (String arg : args) { 25041cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks if (value.equals(arg)) { 25051cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks return true; 25061cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks } 2507a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 2508a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 25091cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks return false; 25101cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks } 2511a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 25126eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey @Override 25131cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) { 25143abd75ba3a981850cac43a401d0014a836559cb0Kenny Root if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 25153abd75ba3a981850cac43a401d0014a836559cb0Kenny Root != PackageManager.PERMISSION_GRANTED) { 25163abd75ba3a981850cac43a401d0014a836559cb0Kenny Root fout.println("Permission Denial: can't dump AccountsManager from from pid=" 25173abd75ba3a981850cac43a401d0014a836559cb0Kenny Root + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 25183abd75ba3a981850cac43a401d0014a836559cb0Kenny Root + " without permission " + android.Manifest.permission.DUMP); 25193abd75ba3a981850cac43a401d0014a836559cb0Kenny Root return; 25203abd75ba3a981850cac43a401d0014a836559cb0Kenny Root } 252104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final boolean isCheckinRequest = scanArgs(args, "--checkin") || scanArgs(args, "-c"); 25226eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey final IndentingPrintWriter ipw = new IndentingPrintWriter(fout, " "); 25236eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey 25246eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey final List<UserInfo> users = getUserManager().getUsers(); 25256eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey for (UserInfo user : users) { 25266eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey ipw.println("User " + user + ":"); 25276eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey ipw.increaseIndent(); 25286eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey dumpUser(getUserAccounts(user.id), fd, ipw, args, isCheckinRequest); 25296eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey ipw.println(); 25306eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey ipw.decreaseIndent(); 253104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 253204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 25331cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks 253404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private void dumpUser(UserAccounts userAccounts, FileDescriptor fd, PrintWriter fout, 253504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani String[] args, boolean isCheckinRequest) { 253604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (userAccounts.cacheLock) { 253704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = userAccounts.openHelper.getReadableDatabase(); 2538a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 2539f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (isCheckinRequest) { 2540f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana // This is a checkin request. *Only* upload the account types and the count of each. 2541f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana Cursor cursor = db.query(TABLE_ACCOUNTS, ACCOUNT_TYPE_COUNT_PROJECTION, 2542f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana null, null, ACCOUNTS_TYPE, null, null); 2543f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana try { 2544f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana while (cursor.moveToNext()) { 2545f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana // print type,count 2546f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana fout.println(cursor.getString(0) + "," + cursor.getString(1)); 2547f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 2548f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } finally { 2549f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (cursor != null) { 2550f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana cursor.close(); 2551f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 25521cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks } 2553f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } else { 2554df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani Account[] accounts = getAccountsFromCacheLocked(userAccounts, null /* type */, 255527db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani Process.myUid(), null); 2556f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana fout.println("Accounts: " + accounts.length); 2557f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana for (Account account : accounts) { 2558f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana fout.println(" " + account); 25591cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks } 2560307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana 2561f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana fout.println(); 2562f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana synchronized (mSessions) { 2563f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana final long now = SystemClock.elapsedRealtime(); 2564f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana fout.println("Active Sessions: " + mSessions.size()); 2565f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana for (Session session : mSessions.values()) { 2566f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana fout.println(" " + session.toDebugString(now)); 2567f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 25681cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks } 25691cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks 2570f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana fout.println(); 25716ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey mAuthenticatorCache.dump(fd, fout, args, userAccounts.userId); 2572f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 25731cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks } 2574a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 2575a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 257604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private void doNotification(UserAccounts accounts, Account account, CharSequence message, 25774120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn Intent intent, int userId) { 257826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 257926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 258026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 258126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana Log.v(TAG, "doNotification: " + message + " intent:" + intent); 258226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 2583a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 2584d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (intent.getComponent() != null && 2585d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana GrantCredentialsPermissionActivity.class.getName().equals( 2586d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana intent.getComponent().getClassName())) { 25874120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn createNoCredentialsPermissionNotification(account, intent, userId); 2588d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } else { 258904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final Integer notificationId = getSigninRequiredNotificationId(accounts, account); 259033f889ae270f888f8fdc084f5f1f3d443532a46aFred Quintana intent.addCategory(String.valueOf(notificationId)); 2591d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Notification n = new Notification(android.R.drawable.stat_sys_warning, null, 2592d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 0 /* when */); 259350cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn UserHandle user = new UserHandle(userId); 259433f889ae270f888f8fdc084f5f1f3d443532a46aFred Quintana final String notificationTitleFormat = 259533f889ae270f888f8fdc084f5f1f3d443532a46aFred Quintana mContext.getText(R.string.notification_title).toString(); 259633f889ae270f888f8fdc084f5f1f3d443532a46aFred Quintana n.setLatestEventInfo(mContext, 259733f889ae270f888f8fdc084f5f1f3d443532a46aFred Quintana String.format(notificationTitleFormat, account.name), 25984120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn message, PendingIntent.getActivityAsUser( 25994120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn mContext, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT, 260050cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn null, user)); 260150cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn installNotification(notificationId, n, user); 2602d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 260326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 260426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 260526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 2606a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 2607a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 260850cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn protected void installNotification(final int notificationId, final Notification n, 260950cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn UserHandle user) { 261056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana ((NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE)) 261150cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn .notifyAsUser(null, notificationId, n, user); 261256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 261356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 261450cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn protected void cancelNotification(int id, UserHandle user) { 261526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 261626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 261726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana ((NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE)) 261850cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn .cancelAsUser(null, id, user); 261926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 262026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 262126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 2622a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 2623d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 2624b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana /** Succeeds if any of the specified permissions are granted. */ 2625b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana private void checkBinderPermission(String... permissions) { 2626d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana final int uid = Binder.getCallingUid(); 2627b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana 2628b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana for (String perm : permissions) { 2629b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana if (mContext.checkCallingOrSelfPermission(perm) == PackageManager.PERMISSION_GRANTED) { 2630b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 263156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, " caller uid " + uid + " has " + perm); 2632b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana } 2633b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana return; 2634b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana } 2635d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2636b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana 2637b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana String msg = "caller uid " + uid + " lacks any of " + TextUtils.join(",", permissions); 263856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.w(TAG, " " + msg); 2639b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana throw new SecurityException(msg); 2640d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2641d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 264267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani private int handleIncomingUser(int userId) { 264367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani try { 264467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani return ActivityManagerNative.getDefault().handleIncomingUser( 264567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani Binder.getCallingPid(), Binder.getCallingUid(), userId, true, true, "", null); 264667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } catch (RemoteException re) { 264767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani // Shouldn't happen, local. 264867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 264967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani return userId; 265067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 265167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani 2652ccbf84f44c9e6a5ed3c08673614826bb237afc54Christopher Tate private boolean isPrivileged(int callingUid) { 26536ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey final int callingUserId = UserHandle.getUserId(callingUid); 26546ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey 26556ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey final PackageManager userPackageManager; 26566ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey try { 26576ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey userPackageManager = mContext.createPackageContextAsUser( 26586ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey "android", 0, new UserHandle(callingUserId)).getPackageManager(); 26596ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey } catch (NameNotFoundException e) { 26606ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey return false; 26616ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey } 26626ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey 26636ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey String[] packages = userPackageManager.getPackagesForUid(callingUid); 26647be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana for (String name : packages) { 26657be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana try { 26666ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey PackageInfo packageInfo = userPackageManager.getPackageInfo(name, 0 /* flags */); 266756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (packageInfo != null 2668ccbf84f44c9e6a5ed3c08673614826bb237afc54Christopher Tate && (packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_PRIVILEGED) != 0) { 26697be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana return true; 26707be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana } 26717be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana } catch (PackageManager.NameNotFoundException e) { 26727be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana return false; 26737be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana } 26747be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana } 26757be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana return false; 26767be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana } 26777be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana 2678d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private boolean permissionIsGranted(Account account, String authTokenType, int callerUid) { 2679ccbf84f44c9e6a5ed3c08673614826bb237afc54Christopher Tate final boolean isPrivileged = isPrivileged(callerUid); 268031957f1badbb900bbfe211317e1ea992d650a72dFred Quintana final boolean fromAuthenticator = account != null 268131957f1badbb900bbfe211317e1ea992d650a72dFred Quintana && hasAuthenticatorUid(account.type, callerUid); 268231957f1badbb900bbfe211317e1ea992d650a72dFred Quintana final boolean hasExplicitGrants = account != null 268304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani && hasExplicitlyGrantedPermission(account, authTokenType, callerUid); 2684d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 2685d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Log.v(TAG, "checkGrantsOrCallingUidAgainstAuthenticator: caller uid " 268656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + callerUid + ", " + account 2687d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + ": is authenticator? " + fromAuthenticator 2688d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + ", has explicit permission? " + hasExplicitGrants); 2689d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2690ccbf84f44c9e6a5ed3c08673614826bb237afc54Christopher Tate return fromAuthenticator || hasExplicitGrants || isPrivileged; 2691d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2692d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 26931a23191bbde11505d6e0c25c04a60b41cb27fd31Fred Quintana private boolean hasAuthenticatorUid(String accountType, int callingUid) { 26946ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey final int callingUserId = UserHandle.getUserId(callingUid); 2695d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana for (RegisteredServicesCache.ServiceInfo<AuthenticatorDescription> serviceInfo : 26966ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey mAuthenticatorCache.getAllServices(callingUserId)) { 2697d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (serviceInfo.type.type.equals(accountType)) { 2698ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana return (serviceInfo.uid == callingUid) || 269956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana (mPackageManager.checkSignatures(serviceInfo.uid, callingUid) 2700ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana == PackageManager.SIGNATURE_MATCH); 2701d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2702d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2703d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana return false; 2704d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2705d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 270604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private boolean hasExplicitlyGrantedPermission(Account account, String authTokenType, 270704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani int callerUid) { 270827db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani if (callerUid == Process.SYSTEM_UID) { 2709d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana return true; 2710d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 271104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 271204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 271304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getReadableDatabase(); 271404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani String[] args = { String.valueOf(callerUid), authTokenType, 2715f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana account.name, account.type}; 2716f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana final boolean permissionGranted = 2717f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana DatabaseUtils.longForQuery(db, COUNT_OF_MATCHING_GRANTS, args) != 0; 2718f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (!permissionGranted && ActivityManager.isRunningInTestHarness()) { 2719f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana // TODO: Skip this check when running automated tests. Replace this 2720f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana // with a more general solution. 2721f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana Log.d(TAG, "no credentials permission for usage of " + account + ", " 272204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani + authTokenType + " by uid " + callerUid 2723f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana + " but ignoring since device is in test harness."); 2724f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return true; 2725f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 2726f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return permissionGranted; 2727d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2728d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2729d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 2730d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private void checkCallingUidAgainstAuthenticator(Account account) { 2731d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana final int uid = Binder.getCallingUid(); 273231957f1badbb900bbfe211317e1ea992d650a72dFred Quintana if (account == null || !hasAuthenticatorUid(account.type, uid)) { 2733d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana String msg = "caller uid " + uid + " is different than the authenticator's uid"; 2734d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Log.w(TAG, msg); 2735d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana throw new SecurityException(msg); 2736d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2737d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 2738d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Log.v(TAG, "caller uid " + uid + " is the same as the authenticator's uid"); 2739d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2740d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2741d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 2742d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private void checkAuthenticateAccountsPermission(Account account) { 2743d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkBinderPermission(Manifest.permission.AUTHENTICATE_ACCOUNTS); 2744d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkCallingUidAgainstAuthenticator(account); 2745d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2746d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 2747d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private void checkReadAccountsPermission() { 2748d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkBinderPermission(Manifest.permission.GET_ACCOUNTS); 2749d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2750d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 2751d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private void checkManageAccountsPermission() { 2752d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkBinderPermission(Manifest.permission.MANAGE_ACCOUNTS); 2753d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2754d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 2755b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana private void checkManageAccountsOrUseCredentialsPermissions() { 2756b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana checkBinderPermission(Manifest.permission.MANAGE_ACCOUNTS, 2757b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana Manifest.permission.USE_CREDENTIALS); 2758b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana } 2759b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana 2760e4cf73437a18c1444055f88a1fcc0d146ec23ac5Amith Yamasani private boolean canUserModifyAccounts(int callingUid) { 276127db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani if (callingUid != Process.myUid()) { 276227db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani if (getUserManager().getUserRestrictions( 276327db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani new UserHandle(UserHandle.getUserId(callingUid))) 276427db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani .getBoolean(UserManager.DISALLOW_MODIFY_ACCOUNTS)) { 2765e4cf73437a18c1444055f88a1fcc0d146ec23ac5Amith Yamasani return false; 2766e4cf73437a18c1444055f88a1fcc0d146ec23ac5Amith Yamasani } 2767e4cf73437a18c1444055f88a1fcc0d146ec23ac5Amith Yamasani } 2768e4cf73437a18c1444055f88a1fcc0d146ec23ac5Amith Yamasani return true; 2769e4cf73437a18c1444055f88a1fcc0d146ec23ac5Amith Yamasani } 2770e4cf73437a18c1444055f88a1fcc0d146ec23ac5Amith Yamasani 277109e7e0ef8bcd8b7b78b79fb570de2032871f0c97Jatin Lodhia @Override 2772d9640ec712806508877868d08aafaa2d715ff441Fred Quintana public void updateAppPermission(Account account, String authTokenType, int uid, boolean value) 2773d9640ec712806508877868d08aafaa2d715ff441Fred Quintana throws RemoteException { 2774d9640ec712806508877868d08aafaa2d715ff441Fred Quintana final int callingUid = getCallingUid(); 2775d9640ec712806508877868d08aafaa2d715ff441Fred Quintana 277627db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani if (callingUid != Process.SYSTEM_UID) { 2777d9640ec712806508877868d08aafaa2d715ff441Fred Quintana throw new SecurityException(); 2778d9640ec712806508877868d08aafaa2d715ff441Fred Quintana } 2779d9640ec712806508877868d08aafaa2d715ff441Fred Quintana 2780d9640ec712806508877868d08aafaa2d715ff441Fred Quintana if (value) { 2781d9640ec712806508877868d08aafaa2d715ff441Fred Quintana grantAppPermission(account, authTokenType, uid); 2782d9640ec712806508877868d08aafaa2d715ff441Fred Quintana } else { 2783d9640ec712806508877868d08aafaa2d715ff441Fred Quintana revokeAppPermission(account, authTokenType, uid); 2784d9640ec712806508877868d08aafaa2d715ff441Fred Quintana } 2785d9640ec712806508877868d08aafaa2d715ff441Fred Quintana } 2786d9640ec712806508877868d08aafaa2d715ff441Fred Quintana 2787d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana /** 2788d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * Allow callers with the given uid permission to get credentials for account/authTokenType. 2789d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * <p> 2790d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * Although this is public it can only be accessed via the AccountManagerService object 2791d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * which is in the system. This means we don't need to protect it with permissions. 2792d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * @hide 2793d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana */ 2794d9640ec712806508877868d08aafaa2d715ff441Fred Quintana private void grantAppPermission(Account account, String authTokenType, int uid) { 2795382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null || authTokenType == null) { 2796382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana Log.e(TAG, "grantAppPermission: called with invalid arguments", new Exception()); 279731957f1badbb900bbfe211317e1ea992d650a72dFred Quintana return; 279831957f1badbb900bbfe211317e1ea992d650a72dFred Quintana } 2799f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackborn UserAccounts accounts = getUserAccounts(UserHandle.getUserId(uid)); 280004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 280104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getWritableDatabase(); 2802f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.beginTransaction(); 2803f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana try { 2804f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana long accountId = getAccountIdLocked(db, account); 2805f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (accountId >= 0) { 2806f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana ContentValues values = new ContentValues(); 2807f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana values.put(GRANTS_ACCOUNTS_ID, accountId); 2808f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana values.put(GRANTS_AUTH_TOKEN_TYPE, authTokenType); 2809f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana values.put(GRANTS_GRANTEE_UID, uid); 2810f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.insert(TABLE_GRANTS, GRANTS_ACCOUNTS_ID, values); 2811f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.setTransactionSuccessful(); 2812f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 2813f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } finally { 2814f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.endTransaction(); 2815d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 281650cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn cancelNotification(getCredentialPermissionNotificationId(account, authTokenType, uid), 281750cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn new UserHandle(accounts.userId)); 2818d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2819d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2820d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 2821d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana /** 2822d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * Don't allow callers with the given uid permission to get credentials for 2823d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * account/authTokenType. 2824d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * <p> 2825d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * Although this is public it can only be accessed via the AccountManagerService object 2826d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * which is in the system. This means we don't need to protect it with permissions. 2827d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * @hide 2828d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana */ 2829d9640ec712806508877868d08aafaa2d715ff441Fred Quintana private void revokeAppPermission(Account account, String authTokenType, int uid) { 2830382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null || authTokenType == null) { 2831382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana Log.e(TAG, "revokeAppPermission: called with invalid arguments", new Exception()); 283231957f1badbb900bbfe211317e1ea992d650a72dFred Quintana return; 283331957f1badbb900bbfe211317e1ea992d650a72dFred Quintana } 2834f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackborn UserAccounts accounts = getUserAccounts(UserHandle.getUserId(uid)); 283504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 283604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getWritableDatabase(); 2837f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.beginTransaction(); 2838f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana try { 2839f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana long accountId = getAccountIdLocked(db, account); 2840f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (accountId >= 0) { 2841f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.delete(TABLE_GRANTS, 2842f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana GRANTS_ACCOUNTS_ID + "=? AND " + GRANTS_AUTH_TOKEN_TYPE + "=? AND " 2843f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana + GRANTS_GRANTEE_UID + "=?", 2844f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana new String[]{String.valueOf(accountId), authTokenType, 2845f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana String.valueOf(uid)}); 2846f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.setTransactionSuccessful(); 2847f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 2848f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } finally { 2849f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.endTransaction(); 2850d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 285150cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn cancelNotification(getCredentialPermissionNotificationId(account, authTokenType, uid), 285250cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn new UserHandle(accounts.userId)); 2853d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2854d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 285556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 285656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana static final private String stringArrayToString(String[] value) { 285756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana return value != null ? ("[" + TextUtils.join(",", value) + "]") : null; 285856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 285956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 286004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private void removeAccountFromCacheLocked(UserAccounts accounts, Account account) { 286104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final Account[] oldAccountsForType = accounts.accountCache.get(account.type); 2862f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (oldAccountsForType != null) { 2863f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana ArrayList<Account> newAccountsList = new ArrayList<Account>(); 2864f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana for (Account curAccount : oldAccountsForType) { 2865f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (!curAccount.equals(account)) { 2866f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana newAccountsList.add(curAccount); 286756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 286856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 2869f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (newAccountsList.isEmpty()) { 287004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.accountCache.remove(account.type); 2871f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } else { 2872f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana Account[] newAccountsForType = new Account[newAccountsList.size()]; 2873f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana newAccountsForType = newAccountsList.toArray(newAccountsForType); 287404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.accountCache.put(account.type, newAccountsForType); 2875f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 287656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 287704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.userDataCache.remove(account); 287804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.authTokenCache.remove(account); 287956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 288056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 288156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana /** 288256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana * This assumes that the caller has already checked that the account is not already present. 288356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana */ 288404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private void insertAccountIntoCacheLocked(UserAccounts accounts, Account account) { 288504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani Account[] accountsForType = accounts.accountCache.get(account.type); 2886f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana int oldLength = (accountsForType != null) ? accountsForType.length : 0; 2887f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana Account[] newAccountsForType = new Account[oldLength + 1]; 2888f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (accountsForType != null) { 2889f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana System.arraycopy(accountsForType, 0, newAccountsForType, 0, oldLength); 2890f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 2891f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana newAccountsForType[oldLength] = account; 289204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.accountCache.put(account.type, newAccountsForType); 2893f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 2894f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana 2895df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani private Account[] filterSharedAccounts(UserAccounts userAccounts, Account[] unfiltered, 289627db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani int callingUid, String callingPackage) { 2897df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani if (getUserManager() == null || userAccounts == null || userAccounts.userId < 0 289827db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani || callingUid == Process.myUid()) { 2899df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani return unfiltered; 2900df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani } 29010c19bf524493f2feedf442d390c878fd1ca66d7bAmith Yamasani UserInfo user = mUserManager.getUserInfo(userAccounts.userId); 29020c19bf524493f2feedf442d390c878fd1ca66d7bAmith Yamasani if (user != null && user.isRestricted()) { 2903df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani String[] packages = mPackageManager.getPackagesForUid(callingUid); 29040ac1fc9d233b8671f371a71e2a6374b47ef069a9Amith Yamasani // If any of the packages is a white listed package, return the full set, 2905df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani // otherwise return non-shared accounts only. 2906df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani // This might be a temporary way to specify a whitelist 2907df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani String whiteList = mContext.getResources().getString( 2908df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani com.android.internal.R.string.config_appsAuthorizedForSharedAccounts); 2909df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani for (String packageName : packages) { 2910df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani if (whiteList.contains(";" + packageName + ";")) { 2911df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani return unfiltered; 2912df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani } 2913df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani } 2914df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani ArrayList<Account> allowed = new ArrayList<Account>(); 2915df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani Account[] sharedAccounts = getSharedAccountsAsUser(userAccounts.userId); 2916df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani if (sharedAccounts == null || sharedAccounts.length == 0) return unfiltered; 29170ac1fc9d233b8671f371a71e2a6374b47ef069a9Amith Yamasani String requiredAccountType = ""; 29180ac1fc9d233b8671f371a71e2a6374b47ef069a9Amith Yamasani try { 2919e3423097044e504c51c68ff88cb91baa1ca68ca9Amith Yamasani // If there's an explicit callingPackage specified, check if that package 2920e3423097044e504c51c68ff88cb91baa1ca68ca9Amith Yamasani // opted in to see restricted accounts. 2921e3423097044e504c51c68ff88cb91baa1ca68ca9Amith Yamasani if (callingPackage != null) { 2922e3423097044e504c51c68ff88cb91baa1ca68ca9Amith Yamasani PackageInfo pi = mPackageManager.getPackageInfo(callingPackage, 0); 29230ac1fc9d233b8671f371a71e2a6374b47ef069a9Amith Yamasani if (pi != null && pi.restrictedAccountType != null) { 29240ac1fc9d233b8671f371a71e2a6374b47ef069a9Amith Yamasani requiredAccountType = pi.restrictedAccountType; 2925e3423097044e504c51c68ff88cb91baa1ca68ca9Amith Yamasani } 2926e3423097044e504c51c68ff88cb91baa1ca68ca9Amith Yamasani } else { 2927e3423097044e504c51c68ff88cb91baa1ca68ca9Amith Yamasani // Otherwise check if the callingUid has a package that has opted in 2928e3423097044e504c51c68ff88cb91baa1ca68ca9Amith Yamasani for (String packageName : packages) { 2929e3423097044e504c51c68ff88cb91baa1ca68ca9Amith Yamasani PackageInfo pi = mPackageManager.getPackageInfo(packageName, 0); 2930e3423097044e504c51c68ff88cb91baa1ca68ca9Amith Yamasani if (pi != null && pi.restrictedAccountType != null) { 2931e3423097044e504c51c68ff88cb91baa1ca68ca9Amith Yamasani requiredAccountType = pi.restrictedAccountType; 293227db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani break; 293327db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani } 2934df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani } 2935df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani } 29360ac1fc9d233b8671f371a71e2a6374b47ef069a9Amith Yamasani } catch (NameNotFoundException nnfe) { 29370ac1fc9d233b8671f371a71e2a6374b47ef069a9Amith Yamasani } 29380ac1fc9d233b8671f371a71e2a6374b47ef069a9Amith Yamasani for (Account account : unfiltered) { 29390ac1fc9d233b8671f371a71e2a6374b47ef069a9Amith Yamasani if (account.type.equals(requiredAccountType)) { 2940df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani allowed.add(account); 29410ac1fc9d233b8671f371a71e2a6374b47ef069a9Amith Yamasani } else { 29420ac1fc9d233b8671f371a71e2a6374b47ef069a9Amith Yamasani boolean found = false; 29430ac1fc9d233b8671f371a71e2a6374b47ef069a9Amith Yamasani for (Account shared : sharedAccounts) { 29440ac1fc9d233b8671f371a71e2a6374b47ef069a9Amith Yamasani if (shared.equals(account)) { 29450ac1fc9d233b8671f371a71e2a6374b47ef069a9Amith Yamasani found = true; 29460ac1fc9d233b8671f371a71e2a6374b47ef069a9Amith Yamasani break; 29470ac1fc9d233b8671f371a71e2a6374b47ef069a9Amith Yamasani } 29480ac1fc9d233b8671f371a71e2a6374b47ef069a9Amith Yamasani } 29490ac1fc9d233b8671f371a71e2a6374b47ef069a9Amith Yamasani if (!found) { 29500ac1fc9d233b8671f371a71e2a6374b47ef069a9Amith Yamasani allowed.add(account); 29510ac1fc9d233b8671f371a71e2a6374b47ef069a9Amith Yamasani } 2952df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani } 2953df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani } 2954df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani Account[] filtered = new Account[allowed.size()]; 2955df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani allowed.toArray(filtered); 2956df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani return filtered; 2957df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani } else { 2958df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani return unfiltered; 2959df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani } 2960df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani } 2961df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani 296227db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani /* 296327db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani * packageName can be null. If not null, it should be used to filter out restricted accounts 296427db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani * that the package is not allowed to access. 296527db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani */ 2966df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani protected Account[] getAccountsFromCacheLocked(UserAccounts userAccounts, String accountType, 296727db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani int callingUid, String callingPackage) { 2968f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (accountType != null) { 296904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final Account[] accounts = userAccounts.accountCache.get(accountType); 2970f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (accounts == null) { 2971f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return EMPTY_ACCOUNT_ARRAY; 297256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } else { 2973df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani return filterSharedAccounts(userAccounts, Arrays.copyOf(accounts, accounts.length), 297427db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani callingUid, callingPackage); 2975f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 2976f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } else { 2977f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana int totalLength = 0; 297804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani for (Account[] accounts : userAccounts.accountCache.values()) { 2979f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana totalLength += accounts.length; 2980f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 2981f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (totalLength == 0) { 2982f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return EMPTY_ACCOUNT_ARRAY; 2983f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 2984f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana Account[] accounts = new Account[totalLength]; 2985f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana totalLength = 0; 298604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani for (Account[] accountsOfType : userAccounts.accountCache.values()) { 2987f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana System.arraycopy(accountsOfType, 0, accounts, totalLength, 2988f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana accountsOfType.length); 2989f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana totalLength += accountsOfType.length; 299056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 299127db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani return filterSharedAccounts(userAccounts, accounts, callingUid, callingPackage); 299256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 299356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 299456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 299504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani protected void writeUserDataIntoCacheLocked(UserAccounts accounts, final SQLiteDatabase db, 299604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani Account account, String key, String value) { 299704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani HashMap<String, String> userDataForAccount = accounts.userDataCache.get(account); 2998f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (userDataForAccount == null) { 2999f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana userDataForAccount = readUserDataForAccountFromDatabaseLocked(db, account); 300004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.userDataCache.put(account, userDataForAccount); 3001f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 3002f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (value == null) { 3003f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana userDataForAccount.remove(key); 3004f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } else { 3005f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana userDataForAccount.put(key, value); 300656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 300756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 300856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 300904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani protected void writeAuthTokenIntoCacheLocked(UserAccounts accounts, final SQLiteDatabase db, 301004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani Account account, String key, String value) { 301104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani HashMap<String, String> authTokensForAccount = accounts.authTokenCache.get(account); 3012f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (authTokensForAccount == null) { 3013f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana authTokensForAccount = readAuthTokensForAccountFromDatabaseLocked(db, account); 301404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.authTokenCache.put(account, authTokensForAccount); 3015f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 3016f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (value == null) { 3017f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana authTokensForAccount.remove(key); 3018f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } else { 3019f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana authTokensForAccount.put(key, value); 302056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 302156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 302256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 302304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani protected String readAuthTokenInternal(UserAccounts accounts, Account account, 302404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani String authTokenType) { 302504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 302604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani HashMap<String, String> authTokensForAccount = accounts.authTokenCache.get(account); 302756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (authTokensForAccount == null) { 302856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana // need to populate the cache for this account 302904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getReadableDatabase(); 3030f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana authTokensForAccount = readAuthTokensForAccountFromDatabaseLocked(db, account); 303104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.authTokenCache.put(account, authTokensForAccount); 303256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 303356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana return authTokensForAccount.get(authTokenType); 303456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 303556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 303656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 303704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani protected String readUserDataInternal(UserAccounts accounts, Account account, String key) { 303804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 303904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani HashMap<String, String> userDataForAccount = accounts.userDataCache.get(account); 304056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (userDataForAccount == null) { 304156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana // need to populate the cache for this account 304204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getReadableDatabase(); 3043f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana userDataForAccount = readUserDataForAccountFromDatabaseLocked(db, account); 304404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.userDataCache.put(account, userDataForAccount); 304556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 304656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana return userDataForAccount.get(key); 304756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 304856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 304956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 3050f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana protected HashMap<String, String> readUserDataForAccountFromDatabaseLocked( 3051f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana final SQLiteDatabase db, Account account) { 305256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana HashMap<String, String> userDataForAccount = new HashMap<String, String>(); 305356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Cursor cursor = db.query(TABLE_EXTRAS, 305456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana COLUMNS_EXTRAS_KEY_AND_VALUE, 305556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana SELECTION_USERDATA_BY_ACCOUNT, 305656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana new String[]{account.name, account.type}, 305756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana null, null, null); 305856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana try { 305956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana while (cursor.moveToNext()) { 306056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final String tmpkey = cursor.getString(0); 306156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final String value = cursor.getString(1); 306256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana userDataForAccount.put(tmpkey, value); 306356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 306456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } finally { 306556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana cursor.close(); 306656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 306756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana return userDataForAccount; 306856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 306956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 3070f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana protected HashMap<String, String> readAuthTokensForAccountFromDatabaseLocked( 3071f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana final SQLiteDatabase db, Account account) { 307256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana HashMap<String, String> authTokensForAccount = new HashMap<String, String>(); 307356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Cursor cursor = db.query(TABLE_AUTHTOKENS, 307456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana COLUMNS_AUTHTOKENS_TYPE_AND_AUTHTOKEN, 307556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana SELECTION_AUTHTOKENS_BY_ACCOUNT, 307656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana new String[]{account.name, account.type}, 307756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana null, null, null); 307856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana try { 307956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana while (cursor.moveToNext()) { 308056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final String type = cursor.getString(0); 308156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final String authToken = cursor.getString(1); 308256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana authTokensForAccount.put(type, authToken); 308356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 308456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } finally { 308556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana cursor.close(); 308656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 308756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana return authTokensForAccount; 308856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 3089603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana} 3090