AccountManagerService.java revision 23c8b96a7e5c3f4c169bf65ae3886357943bb7b0
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; 33885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongkerimport android.app.Notification; 34885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongkerimport android.app.NotificationManager; 35885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongkerimport android.app.PendingIntent; 36a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.content.BroadcastReceiver; 37885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongkerimport android.content.ComponentName; 38a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.content.ContentValues; 39a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.content.Context; 40a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.content.Intent; 41a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.content.IntentFilter; 42b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintanaimport android.content.ServiceConnection; 43885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongkerimport android.content.pm.ApplicationInfo; 44885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongkerimport android.content.pm.PackageInfo; 45d4a1d2e14297a3387fdb5761090961e714370492Fred Quintanaimport android.content.pm.PackageManager; 466ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkeyimport android.content.pm.PackageManager.NameNotFoundException; 47d4a1d2e14297a3387fdb5761090961e714370492Fred Quintanaimport android.content.pm.RegisteredServicesCache; 483ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintanaimport android.content.pm.RegisteredServicesCacheListener; 496eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkeyimport android.content.pm.UserInfo; 50603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintanaimport android.database.Cursor; 51603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintanaimport android.database.DatabaseUtils; 52a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.database.sqlite.SQLiteDatabase; 53a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.database.sqlite.SQLiteOpenHelper; 54885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongkerimport android.os.Binder; 55a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.os.Bundle; 56a8529f68671a8a118751cb6ad577f44eaf076b96Oscar Montemayorimport android.os.Environment; 57a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.os.Handler; 58a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.os.HandlerThread; 59a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.os.IBinder; 60a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.os.Looper; 61a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.os.Message; 6227db46850b708070452c0ce49daf5f79503fbde6Amith Yamasaniimport android.os.Process; 63a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.os.RemoteException; 64a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.os.SystemClock; 65f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackbornimport android.os.UserHandle; 66258848d2ae04f447ff1c18023fa76b139fcc0862Amith Yamasaniimport android.os.UserManager; 67a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.text.TextUtils; 68a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.util.Log; 69d4a1d2e14297a3387fdb5761090961e714370492Fred Quintanaimport android.util.Pair; 706eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkeyimport android.util.Slog; 7104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasaniimport android.util.SparseArray; 72603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 73b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolacheimport com.android.internal.R; 7467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasaniimport com.android.internal.util.ArrayUtils; 7504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasaniimport com.android.internal.util.IndentingPrintWriter; 766ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkeyimport com.google.android.collect.Lists; 776ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkeyimport com.google.android.collect.Sets; 78b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache 79a8529f68671a8a118751cb6ad577f44eaf076b96Oscar Montemayorimport java.io.File; 80a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport java.io.FileDescriptor; 81a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport java.io.PrintWriter; 82a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport java.util.ArrayList; 8356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintanaimport java.util.Arrays; 84a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport java.util.Collection; 85d4a1d2e14297a3387fdb5761090961e714370492Fred Quintanaimport java.util.HashMap; 866ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkeyimport java.util.HashSet; 8756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintanaimport java.util.LinkedHashMap; 886eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkeyimport java.util.List; 892f36229db823d152f3efd879e751e81a601a75b0Andy McFaddenimport java.util.Map; 90d4a1d2e14297a3387fdb5761090961e714370492Fred Quintanaimport java.util.concurrent.atomic.AtomicInteger; 91d4a1d2e14297a3387fdb5761090961e714370492Fred Quintanaimport java.util.concurrent.atomic.AtomicReference; 92603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 93603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana/** 94603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * A system service that provides account, password, and authtoken management for all 95603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * accounts on the device. Some of these calls are implemented with the help of the corresponding 96603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * {@link IAccountAuthenticator} services. This service is not accessed by users directly, 97603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * instead one uses an instance of {@link AccountManager}, which can be accessed as follows: 9846703b099516c383a6882815bcf9cd4df0ec538dBrian Carlstrom * AccountManager accountManager = AccountManager.get(context); 993326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana * @hide 100603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana */ 1013ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintanapublic class AccountManagerService 1023ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintana extends IAccountManager.Stub 1035ebbb4a6b3e16f711735ae0615b9a9ea64faad38Fred Quintana implements RegisteredServicesCacheListener<AuthenticatorDescription> { 104603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String TAG = "AccountManagerService"; 105603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 106603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final int TIMEOUT_DELAY_MS = 1000 * 60; 107603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String DATABASE_NAME = "accounts.db"; 10867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani private static final int DATABASE_VERSION = 5; 109603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 110603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private final Context mContext; 111603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 11256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana private final PackageManager mPackageManager; 113258848d2ae04f447ff1c18023fa76b139fcc0862Amith Yamasani private UserManager mUserManager; 11456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 115603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private HandlerThread mMessageThread; 116603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private final MessageHandler mMessageHandler; 117603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 118603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana // Messages that can be sent on mHandler 119603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final int MESSAGE_TIMED_OUT = 3; 1205be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani private static final int MESSAGE_COPY_SHARED_ACCOUNT = 4; 121603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 12256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana private final IAccountAuthenticatorCache mAuthenticatorCache; 123603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 124603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String TABLE_ACCOUNTS = "accounts"; 125603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String ACCOUNTS_ID = "_id"; 126603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String ACCOUNTS_NAME = "name"; 127603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String ACCOUNTS_TYPE = "type"; 1281cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks private static final String ACCOUNTS_TYPE_COUNT = "count(type)"; 129603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String ACCOUNTS_PASSWORD = "password"; 130603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 131603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String TABLE_AUTHTOKENS = "authtokens"; 132603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String AUTHTOKENS_ID = "_id"; 133603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String AUTHTOKENS_ACCOUNTS_ID = "accounts_id"; 134603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String AUTHTOKENS_TYPE = "type"; 135603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String AUTHTOKENS_AUTHTOKEN = "authtoken"; 136603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 137d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private static final String TABLE_GRANTS = "grants"; 138d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private static final String GRANTS_ACCOUNTS_ID = "accounts_id"; 139d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private static final String GRANTS_AUTH_TOKEN_TYPE = "auth_token_type"; 140d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private static final String GRANTS_GRANTEE_UID = "uid"; 141d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 142603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String TABLE_EXTRAS = "extras"; 143603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String EXTRAS_ID = "_id"; 144603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String EXTRAS_ACCOUNTS_ID = "accounts_id"; 145603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String EXTRAS_KEY = "key"; 146603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String EXTRAS_VALUE = "value"; 147603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 148603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String TABLE_META = "meta"; 149603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String META_KEY = "key"; 150603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String META_VALUE = "value"; 151603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 15267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani private static final String TABLE_SHARED_ACCOUNTS = "shared_accounts"; 15367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani 1541cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks private static final String[] ACCOUNT_TYPE_COUNT_PROJECTION = 1551cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks new String[] { ACCOUNTS_TYPE, ACCOUNTS_TYPE_COUNT}; 1567be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana private static final Intent ACCOUNTS_CHANGED_INTENT; 157a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 158d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private static final String COUNT_OF_MATCHING_GRANTS = "" 159d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + "SELECT COUNT(*) FROM " + TABLE_GRANTS + ", " + TABLE_ACCOUNTS 160d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + " WHERE " + GRANTS_ACCOUNTS_ID + "=" + ACCOUNTS_ID 161d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + " AND " + GRANTS_GRANTEE_UID + "=?" 162d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + " AND " + GRANTS_AUTH_TOKEN_TYPE + "=?" 163d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + " AND " + ACCOUNTS_NAME + "=?" 164d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + " AND " + ACCOUNTS_TYPE + "=?"; 165d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 16656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana private static final String SELECTION_AUTHTOKENS_BY_ACCOUNT = 16756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana AUTHTOKENS_ACCOUNTS_ID + "=(select _id FROM accounts WHERE name=? AND type=?)"; 16856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana private static final String[] COLUMNS_AUTHTOKENS_TYPE_AND_AUTHTOKEN = {AUTHTOKENS_TYPE, 16956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana AUTHTOKENS_AUTHTOKEN}; 17056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 17156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana private static final String SELECTION_USERDATA_BY_ACCOUNT = 17256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana EXTRAS_ACCOUNTS_ID + "=(select _id FROM accounts WHERE name=? AND type=?)"; 17356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana private static final String[] COLUMNS_EXTRAS_KEY_AND_VALUE = {EXTRAS_KEY, EXTRAS_VALUE}; 17456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 175a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana private final LinkedHashMap<String, Session> mSessions = new LinkedHashMap<String, Session>(); 176d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private final AtomicInteger mNotificationIds = new AtomicInteger(1); 177d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 17804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani static class UserAccounts { 17904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private final int userId; 18004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private final DatabaseHelper openHelper; 18104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private final HashMap<Pair<Pair<Account, String>, Integer>, Integer> 18204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani credentialsPermissionNotificationIds = 18304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani new HashMap<Pair<Pair<Account, String>, Integer>, Integer>(); 18404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private final HashMap<Account, Integer> signinRequiredNotificationIds = 18504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani new HashMap<Account, Integer>(); 18604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private final Object cacheLock = new Object(); 18704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani /** protected by the {@link #cacheLock} */ 188b483a99c6bdfee72fbb8fbcf893e63ef3f54658bAmith Yamasani private final HashMap<String, Account[]> accountCache = 189b483a99c6bdfee72fbb8fbcf893e63ef3f54658bAmith Yamasani new LinkedHashMap<String, Account[]>(); 19004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani /** protected by the {@link #cacheLock} */ 19104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private HashMap<Account, HashMap<String, String>> userDataCache = 19204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani new HashMap<Account, HashMap<String, String>>(); 19304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani /** protected by the {@link #cacheLock} */ 19404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private HashMap<Account, HashMap<String, String>> authTokenCache = 19504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani new HashMap<Account, HashMap<String, String>>(); 19604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani 19704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts(Context context, int userId) { 19804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani this.userId = userId; 19904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (cacheLock) { 20004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani openHelper = new DatabaseHelper(context, userId); 20104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 20204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 20304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 20404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani 20504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private final SparseArray<UserAccounts> mUsers = new SparseArray<UserAccounts>(); 20604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani 207d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private static AtomicReference<AccountManagerService> sThis = 208d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana new AtomicReference<AccountManagerService>(); 20931957f1badbb900bbfe211317e1ea992d650a72dFred Quintana private static final Account[] EMPTY_ACCOUNT_ARRAY = new Account[]{}; 2107be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana 2117be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana static { 212f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana ACCOUNTS_CHANGED_INTENT = new Intent(AccountManager.LOGIN_ACCOUNTS_CHANGED_ACTION); 2137be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana ACCOUNTS_CHANGED_INTENT.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 2147be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana } 2157be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana 21656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 217d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana /** 218d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * This should only be called by system code. One should only call this after the service 219d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * has started. 220d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * @return a reference to the AccountManagerService instance 221d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * @hide 222d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana */ 223d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana public static AccountManagerService getSingleton() { 224d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana return sThis.get(); 225d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 226603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 22756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana public AccountManagerService(Context context) { 22856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana this(context, context.getPackageManager(), new AccountAuthenticatorCache(context)); 229603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 230603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 23156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana public AccountManagerService(Context context, PackageManager packageManager, 23256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana IAccountAuthenticatorCache authenticatorCache) { 233603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mContext = context; 23456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana mPackageManager = packageManager; 235603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 236603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mMessageThread = new HandlerThread("AccountManagerService"); 237603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mMessageThread.start(); 238603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mMessageHandler = new MessageHandler(mMessageThread.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 27126ff6626fc4ee0ae46f01ad309b366921da589feKenny Root public void systemReady() { 27226ff6626fc4ee0ae46f01ad309b366921da589feKenny Root } 27326ff6626fc4ee0ae46f01ad309b366921da589feKenny Root 274258848d2ae04f447ff1c18023fa76b139fcc0862Amith Yamasani private UserManager getUserManager() { 275258848d2ae04f447ff1c18023fa76b139fcc0862Amith Yamasani if (mUserManager == null) { 27627db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani mUserManager = UserManager.get(mContext); 277258848d2ae04f447ff1c18023fa76b139fcc0862Amith Yamasani } 278258848d2ae04f447ff1c18023fa76b139fcc0862Amith Yamasani return mUserManager; 279258848d2ae04f447ff1c18023fa76b139fcc0862Amith Yamasani } 280258848d2ae04f447ff1c18023fa76b139fcc0862Amith Yamasani 28104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private UserAccounts initUser(int userId) { 28204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (mUsers) { 28304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = mUsers.get(userId); 28404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani if (accounts == null) { 28504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts = new UserAccounts(mContext, userId); 28604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani mUsers.append(userId, accounts); 28704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani purgeOldGrants(accounts); 2886eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey validateAccountsInternal(accounts, true /* invalidateAuthenticatorCache */); 28904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 29004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani return accounts; 29104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 29204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 29304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani 29404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private void purgeOldGrantsAll() { 29504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (mUsers) { 29604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani for (int i = 0; i < mUsers.size(); i++) { 29704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani purgeOldGrants(mUsers.valueAt(i)); 29804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 29904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 30004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 30104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani 30204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private void purgeOldGrants(UserAccounts accounts) { 30304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 30404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getWritableDatabase(); 305c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana final Cursor cursor = db.query(TABLE_GRANTS, 306c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana new String[]{GRANTS_GRANTEE_UID}, 307c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana null, null, GRANTS_GRANTEE_UID, null, null); 308c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana try { 309c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana while (cursor.moveToNext()) { 310c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana final int uid = cursor.getInt(0); 311c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana final boolean packageExists = mPackageManager.getPackagesForUid(uid) != null; 312c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana if (packageExists) { 313c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana continue; 314c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana } 315c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana Log.d(TAG, "deleting grants for UID " + uid 316c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana + " because its package is no longer installed"); 317c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana db.delete(TABLE_GRANTS, GRANTS_GRANTEE_UID + "=?", 318c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana new String[]{Integer.toString(uid)}); 319c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana } 320c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana } finally { 321c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana cursor.close(); 322c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana } 323c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana } 324c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana } 325c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana 3266eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey /** 3276eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey * Validate internal set of accounts against installed authenticators for 3286eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey * given user. Clears cached authenticators before validating. 3296eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey */ 3306eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey public void validateAccounts(int userId) { 3316eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey final UserAccounts accounts = getUserAccounts(userId); 3326eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey 3336eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey // Invalidate user-specific cache to make sure we catch any 3346eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey // removed authenticators. 3356eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey validateAccountsInternal(accounts, true /* invalidateAuthenticatorCache */); 3366eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey } 3376eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey 3386eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey /** 3396eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey * Validate internal set of accounts against installed authenticators for 3406eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey * given user. Clear cached authenticators before validating when requested. 3416eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey */ 3426eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey private void validateAccountsInternal( 3436eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey UserAccounts accounts, boolean invalidateAuthenticatorCache) { 3446eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey if (invalidateAuthenticatorCache) { 3456eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey mAuthenticatorCache.invalidateCache(accounts.userId); 3466eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey } 3476eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey 3486ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey final HashSet<AuthenticatorDescription> knownAuth = Sets.newHashSet(); 3496ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey for (RegisteredServicesCache.ServiceInfo<AuthenticatorDescription> service : 3506ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey mAuthenticatorCache.getAllServices(accounts.userId)) { 3516ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey knownAuth.add(service.type); 3526ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey } 3536ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey 35404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 35504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getWritableDatabase(); 356f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana boolean accountDeleted = false; 357f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana Cursor cursor = db.query(TABLE_ACCOUNTS, 358f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana new String[]{ACCOUNTS_ID, ACCOUNTS_TYPE, ACCOUNTS_NAME}, 359f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana null, null, null, null, null); 360f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana try { 36104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.accountCache.clear(); 36256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final HashMap<String, ArrayList<String>> accountNamesByType = 363b483a99c6bdfee72fbb8fbcf893e63ef3f54658bAmith Yamasani new LinkedHashMap<String, ArrayList<String>>(); 36456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana while (cursor.moveToNext()) { 36556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final long accountId = cursor.getLong(0); 36656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final String accountType = cursor.getString(1); 36756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final String accountName = cursor.getString(2); 3686ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey 3696ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey if (!knownAuth.contains(AuthenticatorDescription.newKey(accountType))) { 3706eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey Slog.w(TAG, "deleting account " + accountName + " because type " 37156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + accountType + " no longer has a registered authenticator"); 37256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana db.delete(TABLE_ACCOUNTS, ACCOUNTS_ID + "=" + accountId, null); 37356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana accountDeleted = true; 37456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final Account account = new Account(accountName, accountType); 37504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.userDataCache.remove(account); 37604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.authTokenCache.remove(account); 37756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } else { 37856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana ArrayList<String> accountNames = accountNamesByType.get(accountType); 37956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (accountNames == null) { 38056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana accountNames = new ArrayList<String>(); 38156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana accountNamesByType.put(accountType, accountNames); 38256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 38356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana accountNames.add(accountName); 38456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 38556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 3862f36229db823d152f3efd879e751e81a601a75b0Andy McFadden for (Map.Entry<String, ArrayList<String>> cur 387f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana : accountNamesByType.entrySet()) { 38856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final String accountType = cur.getKey(); 38956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final ArrayList<String> accountNames = cur.getValue(); 39056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final Account[] accountsForType = new Account[accountNames.size()]; 39156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana int i = 0; 39256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana for (String accountName : accountNames) { 39356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana accountsForType[i] = new Account(accountName, accountType); 39456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana ++i; 39556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 39604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.accountCache.put(accountType, accountsForType); 397afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana } 398f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } finally { 399f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana cursor.close(); 400f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (accountDeleted) { 40104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani sendAccountsChangedBroadcast(accounts.userId); 402f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 403afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana } 404afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana } 4053ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintana } 4063ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintana 40704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private UserAccounts getUserAccountsForCaller() { 408f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackborn return getUserAccounts(UserHandle.getCallingUserId()); 40904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 41004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani 41104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani protected UserAccounts getUserAccounts(int userId) { 41204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (mUsers) { 41304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = mUsers.get(userId); 41404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani if (accounts == null) { 41504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts = initUser(userId); 41604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani mUsers.append(userId, accounts); 41704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 41804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani return accounts; 41904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 42004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 42104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani 422135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani private void onUserRemoved(Intent intent) { 4232a00329c6d55c6cd9166e01963d7410e95d80d21Amith Yamasani int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); 424135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani if (userId < 1) return; 425135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani 426135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani UserAccounts accounts; 427135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani synchronized (mUsers) { 428135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani accounts = mUsers.get(userId); 429135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani mUsers.remove(userId); 430135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani } 431135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani if (accounts == null) { 432135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani File dbFile = new File(getDatabaseName(userId)); 433135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani dbFile.delete(); 434135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani return; 435135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani } 436135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani 437135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani synchronized (accounts.cacheLock) { 438135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani accounts.openHelper.close(); 439135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani File dbFile = new File(getDatabaseName(userId)); 440135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani dbFile.delete(); 441135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani } 442135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani } 443135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani 44467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani private void onUserStarted(Intent intent) { 44567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); 44667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani if (userId < 1) return; 44767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani 44867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani // Check if there's a shared account that needs to be created as an account 44967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani Account[] sharedAccounts = getSharedAccountsAsUser(userId); 45067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani if (sharedAccounts == null || sharedAccounts.length == 0) return; 45167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani Account[] accounts = getAccountsAsUser(null, userId); 45267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani for (Account sa : sharedAccounts) { 45367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani if (ArrayUtils.contains(accounts, sa)) continue; 45467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani // Account doesn't exist. Copy it now. 45567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani copyAccountToUser(sa, UserHandle.USER_OWNER, userId); 45667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 45767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 45867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani 4596ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey @Override 4606ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey public void onServiceChanged(AuthenticatorDescription desc, int userId, boolean removed) { 4616eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey validateAccountsInternal(getUserAccounts(userId), false /* invalidateAuthenticatorCache */); 462603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 463603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 464a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public String getPassword(Account account) { 46556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 46656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "getPassword: " + account 46756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 46856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 46956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 470382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 471d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkAuthenticateAccountsPermission(account); 472d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 47304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 47426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 475603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana try { 47604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani return readPasswordInternal(accounts, account); 477603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } finally { 47826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 479603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 480603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 481603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 48204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private String readPasswordInternal(UserAccounts accounts, Account account) { 48331957f1badbb900bbfe211317e1ea992d650a72dFred Quintana if (account == null) { 48431957f1badbb900bbfe211317e1ea992d650a72dFred Quintana return null; 48531957f1badbb900bbfe211317e1ea992d650a72dFred Quintana } 48631957f1badbb900bbfe211317e1ea992d650a72dFred Quintana 48704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 48804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getReadableDatabase(); 489f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana Cursor cursor = db.query(TABLE_ACCOUNTS, new String[]{ACCOUNTS_PASSWORD}, 490f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?", 491f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana new String[]{account.name, account.type}, null, null, null); 492f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana try { 493f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (cursor.moveToNext()) { 494f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return cursor.getString(0); 495f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 496f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return null; 497f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } finally { 498f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana cursor.close(); 499ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 500ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 501ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 502ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 503a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public String getUserData(Account account, String key) { 50456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 50556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "getUserData: " + account 50656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", key " + key 50756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 50856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 50956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 510382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 511382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (key == null) throw new IllegalArgumentException("key is null"); 512d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkAuthenticateAccountsPermission(account); 51304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 51426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 515603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana try { 51604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani return readUserDataInternal(accounts, account, key); 517ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } finally { 518ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana restoreCallingIdentity(identityToken); 519ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 520ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 521ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 5229788976b1465ce982b5ae7c741345edd0ecd9322Fred Quintana public AuthenticatorDescription[] getAuthenticatorTypes() { 52356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 52456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "getAuthenticatorTypes: " 52556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + "caller's uid " + Binder.getCallingUid() 52656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 52756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 5286ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey final int userId = UserHandle.getCallingUserId(); 5296ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey final long identityToken = clearCallingIdentity(); 53026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 5319788976b1465ce982b5ae7c741345edd0ecd9322Fred Quintana Collection<AccountAuthenticatorCache.ServiceInfo<AuthenticatorDescription>> 5326ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey authenticatorCollection = mAuthenticatorCache.getAllServices(userId); 5339788976b1465ce982b5ae7c741345edd0ecd9322Fred Quintana AuthenticatorDescription[] types = 5349788976b1465ce982b5ae7c741345edd0ecd9322Fred Quintana new AuthenticatorDescription[authenticatorCollection.size()]; 53526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana int i = 0; 5369788976b1465ce982b5ae7c741345edd0ecd9322Fred Quintana for (AccountAuthenticatorCache.ServiceInfo<AuthenticatorDescription> authenticator 537718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana : authenticatorCollection) { 538718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana types[i] = authenticator.type; 53926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana i++; 54026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 54126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana return types; 54226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 54326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 544a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 545a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 546a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 5473df7d697ca86ee2081bcfba31bcbd3ae4f4bcdf8Jatin Lodhia @Override 54827db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani public boolean addAccountExplicitly(Account account, String password, Bundle extras) { 54956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 55027db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani Log.v(TAG, "addAccountExplicitly: " + account 55156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 55256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 55356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 554382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 555d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkAuthenticateAccountsPermission(account); 5563df7d697ca86ee2081bcfba31bcbd3ae4f4bcdf8Jatin Lodhia /* 5573df7d697ca86ee2081bcfba31bcbd3ae4f4bcdf8Jatin Lodhia * Child users are not allowed to add accounts. Only the accounts that are 5583df7d697ca86ee2081bcfba31bcbd3ae4f4bcdf8Jatin Lodhia * shared by the parent profile can be added to child profile. 5593df7d697ca86ee2081bcfba31bcbd3ae4f4bcdf8Jatin Lodhia * 5603df7d697ca86ee2081bcfba31bcbd3ae4f4bcdf8Jatin Lodhia * TODO: Only allow accounts that were shared to be added by 5613df7d697ca86ee2081bcfba31bcbd3ae4f4bcdf8Jatin Lodhia * a limited user. 5623df7d697ca86ee2081bcfba31bcbd3ae4f4bcdf8Jatin Lodhia */ 563d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 56404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 565603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana // fails if the account already exists 56626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 567603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana try { 56867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani return addAccountInternal(accounts, account, password, extras, false); 56967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } finally { 57067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani restoreCallingIdentity(identityToken); 57167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 57267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 57367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani 57467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani private boolean copyAccountToUser(final Account account, int userFrom, int userTo) { 57567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani final UserAccounts fromAccounts = getUserAccounts(userFrom); 57667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani final UserAccounts toAccounts = getUserAccounts(userTo); 57767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani if (fromAccounts == null || toAccounts == null) { 57867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani return false; 57967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 58067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani 58167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani long identityToken = clearCallingIdentity(); 58267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani try { 58367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani new Session(fromAccounts, null, account.type, false, 58467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani false /* stripAuthTokenFromResult */) { 58567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani protected String toDebugString(long now) { 58667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani return super.toDebugString(now) + ", getAccountCredentialsForClone" 58767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani + ", " + account.type; 58867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 58967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani 59067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani public void run() throws RemoteException { 59167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani mAuthenticator.getAccountCredentialsForCloning(this, account); 59267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 59367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani 59467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani public void onResult(Bundle result) { 59567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani if (result != null) { 59667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani if (result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT, false)) { 59767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani // Create a Session for the target user and pass in the bundle 59867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani completeCloningAccount(result, account, toAccounts); 59967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 60067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani return; 60167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } else { 60267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani super.onResult(result); 60367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 60467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 60567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani }.bind(); 606ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } finally { 607ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana restoreCallingIdentity(identityToken); 608ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 60967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani return true; 61067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 61167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani 61267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani void completeCloningAccount(final Bundle result, final Account account, 61367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani final UserAccounts targetUser) { 61467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani long id = clearCallingIdentity(); 61567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani try { 61667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani new Session(targetUser, null, account.type, false, 61767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani false /* stripAuthTokenFromResult */) { 61867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani protected String toDebugString(long now) { 61967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani return super.toDebugString(now) + ", getAccountCredentialsForClone" 62067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani + ", " + account.type; 62167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 62267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani 62367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani public void run() throws RemoteException { 6245be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani // Confirm that the owner's account still exists before this step. 6255be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani UserAccounts owner = getUserAccounts(UserHandle.USER_OWNER); 6265be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani synchronized (owner.cacheLock) { 6275be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani Account[] ownerAccounts = getAccounts(UserHandle.USER_OWNER); 6285be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani for (Account acc : ownerAccounts) { 6295be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani if (acc.equals(account)) { 6305be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani mAuthenticator.addAccountFromCredentials(this, account, result); 6315be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani break; 6325be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani } 6335be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani } 6345be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani } 63567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 63667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani 63767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani public void onResult(Bundle result) { 63867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani if (result != null) { 63967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani if (result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT, false)) { 64067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani // TODO: Anything? 64167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } else { 64267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani // TODO: Show error notification 64367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani // TODO: Should we remove the shadow account to avoid retries? 64467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 64567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani return; 64667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } else { 64767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani super.onResult(result); 64867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 64967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 65067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani 65167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani public void onError(int errorCode, String errorMessage) { 65267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani super.onError(errorCode, errorMessage); 65367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani // TODO: Show error notification to user 65467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani // TODO: Should we remove the shadow account so that it doesn't keep trying? 65567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 65667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani 65767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani }.bind(); 65867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } finally { 65967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani restoreCallingIdentity(id); 66067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 661ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 662ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 66304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private boolean addAccountInternal(UserAccounts accounts, Account account, String password, 66467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani Bundle extras, boolean restricted) { 665743dfad2a51e016ddb741c104317637089187753Fred Quintana if (account == null) { 666743dfad2a51e016ddb741c104317637089187753Fred Quintana return false; 667743dfad2a51e016ddb741c104317637089187753Fred Quintana } 66804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 66904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getWritableDatabase(); 670f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.beginTransaction(); 671f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana try { 672f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana long numMatches = DatabaseUtils.longForQuery(db, 673f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana "select count(*) from " + TABLE_ACCOUNTS 674f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana + " WHERE " + ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?", 675f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana new String[]{account.name, account.type}); 676f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (numMatches > 0) { 677f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana Log.w(TAG, "insertAccountIntoDatabase: " + account 678f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana + ", skipping since the account already exists"); 679f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return false; 680f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 681f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana ContentValues values = new ContentValues(); 682f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana values.put(ACCOUNTS_NAME, account.name); 683f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana values.put(ACCOUNTS_TYPE, account.type); 684f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana values.put(ACCOUNTS_PASSWORD, password); 685f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana long accountId = db.insert(TABLE_ACCOUNTS, ACCOUNTS_NAME, values); 686f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (accountId < 0) { 687f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana Log.w(TAG, "insertAccountIntoDatabase: " + account 688f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana + ", skipping the DB insert failed"); 689f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return false; 690f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 691f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (extras != null) { 692f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana for (String key : extras.keySet()) { 693f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana final String value = extras.getString(key); 694f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (insertExtraLocked(db, accountId, key, value) < 0) { 695f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana Log.w(TAG, "insertAccountIntoDatabase: " + account 696f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana + ", skipping since insertExtra failed for key " + key); 697f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return false; 698f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 699603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 700603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 701f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.setTransactionSuccessful(); 70204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani insertAccountIntoCacheLocked(accounts, account); 703f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } finally { 704f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.endTransaction(); 705603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 70604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani sendAccountsChangedBroadcast(accounts.userId); 7075be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani } 7085be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani if (accounts.userId == UserHandle.USER_OWNER) { 7095be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani addAccountToLimitedUsers(account); 7105be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani } 7115be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani return true; 7125be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani } 7135be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani 7145be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani /** 7155be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani * Adds the account to all limited users as shared accounts. If the user is currently 7165be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani * running, then clone the account too. 7175be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani * @param account the account to share with limited users 7185be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani */ 7195be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani private void addAccountToLimitedUsers(Account account) { 720f4c240e68a3da9f1ebf42267c88af40c19ff49daMita Yun List<UserInfo> users = getUserManager().getUsers(); 7215be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani for (UserInfo user : users) { 7225be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani if (user.isRestricted()) { 7235be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani addSharedAccountAsUser(account, user.id); 7245be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani try { 7255be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani if (ActivityManagerNative.getDefault().isUserRunning(user.id, false)) { 7265be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani mMessageHandler.sendMessage(mMessageHandler.obtainMessage( 7275be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani MESSAGE_COPY_SHARED_ACCOUNT, UserHandle.USER_OWNER, user.id, 7285be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani account)); 7295be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani } 7305be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani } catch (RemoteException re) { 7315be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani // Shouldn't happen 7325be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani } 7335be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani } 734603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 735603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 736603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 737f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana private long insertExtraLocked(SQLiteDatabase db, long accountId, String key, String value) { 738603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana ContentValues values = new ContentValues(); 739603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana values.put(EXTRAS_KEY, key); 740603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana values.put(EXTRAS_ACCOUNTS_ID, accountId); 741603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana values.put(EXTRAS_VALUE, value); 742603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana return db.insert(TABLE_EXTRAS, EXTRAS_KEY, values); 743603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 744603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 7453084a6f80180506ce26fe4773d9a19f004b7f625Fred Quintana public void hasFeatures(IAccountManagerResponse response, 746bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana Account account, String[] features) { 74756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 74856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "hasFeatures: " + account 74956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", response " + response 75056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", features " + stringArrayToString(features) 75156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 75256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 75356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 754382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (response == null) throw new IllegalArgumentException("response is null"); 755382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 756382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (features == null) throw new IllegalArgumentException("features is null"); 757bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana checkReadAccountsPermission(); 75804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 759bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana long identityToken = clearCallingIdentity(); 760bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana try { 76104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani new TestFeaturesSession(accounts, response, account, features).bind(); 762bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } finally { 763bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana restoreCallingIdentity(identityToken); 764bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 765bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 766bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana 767bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana private class TestFeaturesSession extends Session { 768bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana private final String[] mFeatures; 769bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana private final Account mAccount; 770bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana 77104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani public TestFeaturesSession(UserAccounts accounts, IAccountManagerResponse response, 772bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana Account account, String[] features) { 77304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani super(accounts, response, account.type, false /* expectActivityLaunch */, 7748570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana true /* stripAuthTokenFromResult */); 775bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana mFeatures = features; 776bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana mAccount = account; 777bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 778bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana 779bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana public void run() throws RemoteException { 780bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana try { 781bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana mAuthenticator.hasFeatures(this, mAccount, mFeatures); 782bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } catch (RemoteException e) { 783bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana onError(AccountManager.ERROR_CODE_REMOTE_EXCEPTION, "remote exception"); 784bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 785bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 786bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana 787bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana public void onResult(Bundle result) { 788bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana IAccountManagerResponse response = getResponseAndClose(); 789bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana if (response != null) { 790bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana try { 791bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana if (result == null) { 792166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana response.onError(AccountManager.ERROR_CODE_INVALID_RESPONSE, "null bundle"); 793bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana return; 794bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 79556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 79656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, getClass().getSimpleName() + " calling onResult() on response " 79756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + response); 79856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 799bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana final Bundle newResult = new Bundle(); 800bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana newResult.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, 801bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT, false)); 802bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana response.onResult(newResult); 803bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } catch (RemoteException e) { 804bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana // if the caller is dead then there is no one to care about remote exceptions 805bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 806bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana Log.v(TAG, "failure while notifying response", e); 807bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 808bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 809bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 810bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 811bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana 812bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana protected String toDebugString(long now) { 8133084a6f80180506ce26fe4773d9a19f004b7f625Fred Quintana return super.toDebugString(now) + ", hasFeatures" 814bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana + ", " + mAccount 815bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana + ", " + (mFeatures != null ? TextUtils.join(",", mFeatures) : null); 816bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 817bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 818307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana 819ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana public void removeAccount(IAccountManagerResponse response, Account account) { 82056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 82156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "removeAccount: " + account 82256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", response " + response 82356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 82456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 82556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 826382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (response == null) throw new IllegalArgumentException("response is null"); 827382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 828d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkManageAccountsPermission(); 82950cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn UserHandle user = Binder.getCallingUserHandle(); 83004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 831e4cf73437a18c1444055f88a1fcc0d146ec23ac5Amith Yamasani if (!canUserModifyAccounts(Binder.getCallingUid())) { 832e4cf73437a18c1444055f88a1fcc0d146ec23ac5Amith Yamasani try { 833e4cf73437a18c1444055f88a1fcc0d146ec23ac5Amith Yamasani response.onError(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION, 834e4cf73437a18c1444055f88a1fcc0d146ec23ac5Amith Yamasani "User cannot modify accounts"); 835e4cf73437a18c1444055f88a1fcc0d146ec23ac5Amith Yamasani } catch (RemoteException re) { 836e4cf73437a18c1444055f88a1fcc0d146ec23ac5Amith Yamasani } 837e4cf73437a18c1444055f88a1fcc0d146ec23ac5Amith Yamasani } 838e4cf73437a18c1444055f88a1fcc0d146ec23ac5Amith Yamasani 83926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 840ec0c4f4183630a64c2b2cc8f961dc7e11cc628caCostin Manolache 84150cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn cancelNotification(getSigninRequiredNotificationId(accounts, account), user); 84204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized(accounts.credentialsPermissionNotificationIds) { 843ec0c4f4183630a64c2b2cc8f961dc7e11cc628caCostin Manolache for (Pair<Pair<Account, String>, Integer> pair: 84404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.credentialsPermissionNotificationIds.keySet()) { 845ec0c4f4183630a64c2b2cc8f961dc7e11cc628caCostin Manolache if (account.equals(pair.first.first)) { 84604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani int id = accounts.credentialsPermissionNotificationIds.get(pair); 84750cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn cancelNotification(id, user); 848ec0c4f4183630a64c2b2cc8f961dc7e11cc628caCostin Manolache } 849ec0c4f4183630a64c2b2cc8f961dc7e11cc628caCostin Manolache } 850ec0c4f4183630a64c2b2cc8f961dc7e11cc628caCostin Manolache } 851ec0c4f4183630a64c2b2cc8f961dc7e11cc628caCostin Manolache 85226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 85304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani new RemoveAccountSession(accounts, response, account).bind(); 85426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 85526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 856a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 857603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 858603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 859ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana private class RemoveAccountSession extends Session { 860ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana final Account mAccount; 86104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani public RemoveAccountSession(UserAccounts accounts, IAccountManagerResponse response, 86204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani Account account) { 86304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani super(accounts, response, account.type, false /* expectActivityLaunch */, 8648570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana true /* stripAuthTokenFromResult */); 865ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana mAccount = account; 866ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 867ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 868ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana protected String toDebugString(long now) { 869ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana return super.toDebugString(now) + ", removeAccount" 870ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana + ", account " + mAccount; 871ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 872ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 873ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana public void run() throws RemoteException { 874ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana mAuthenticator.getAccountRemovalAllowed(this, mAccount); 875ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 876ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 877ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana public void onResult(Bundle result) { 878f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana if (result != null && result.containsKey(AccountManager.KEY_BOOLEAN_RESULT) 879f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana && !result.containsKey(AccountManager.KEY_INTENT)) { 880f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana final boolean removalAllowed = result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT); 881ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana if (removalAllowed) { 88204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani removeAccountInternal(mAccounts, mAccount); 883ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 884ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana IAccountManagerResponse response = getResponseAndClose(); 885ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana if (response != null) { 88656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 88756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, getClass().getSimpleName() + " calling onResult() on response " 88856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + response); 88956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 890ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana Bundle result2 = new Bundle(); 891f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana result2.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, removalAllowed); 892ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana try { 893ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana response.onResult(result2); 894ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } catch (RemoteException e) { 895ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana // ignore 896ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 897ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 898ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 899ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana super.onResult(result); 900ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 901ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 902ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 90304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani /* For testing */ 904f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana protected void removeAccountInternal(Account account) { 90504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani removeAccountInternal(getUserAccountsForCaller(), account); 90604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 90704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani 90804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private void removeAccountInternal(UserAccounts accounts, Account account) { 90904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 91004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getWritableDatabase(); 911f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.delete(TABLE_ACCOUNTS, ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?", 912f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana new String[]{account.name, account.type}); 91304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani removeAccountFromCacheLocked(accounts, account); 91404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani sendAccountsChangedBroadcast(accounts.userId); 915f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 91667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani if (accounts.userId == UserHandle.USER_OWNER) { 91767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani // Owner's account was removed, remove from any users that are sharing 91867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani // this account. 91967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani long id = Binder.clearCallingIdentity(); 92067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani try { 92167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani List<UserInfo> users = mUserManager.getUsers(true); 92267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani for (UserInfo user : users) { 92367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani if (!user.isPrimary() && user.isRestricted()) { 92467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani removeSharedAccountAsUser(account, user.id); 92567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 92667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 92767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } finally { 92867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani Binder.restoreCallingIdentity(id); 92967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 93067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 931ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 932ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 933a12fccf57d5ec289793699d9b22ff45daccd3933Maggie Benthall @Override 934a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void invalidateAuthToken(String accountType, String authToken) { 93556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 93656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "invalidateAuthToken: accountType " + accountType 93756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 93856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 93956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 940382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (accountType == null) throw new IllegalArgumentException("accountType is null"); 941382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (authToken == null) throw new IllegalArgumentException("authToken is null"); 942b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana checkManageAccountsOrUseCredentialsPermissions(); 94304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 94426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 945603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana try { 94604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 94704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getWritableDatabase(); 948f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.beginTransaction(); 949f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana try { 95004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani invalidateAuthTokenLocked(accounts, db, accountType, authToken); 951f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.setTransactionSuccessful(); 952f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } finally { 953f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.endTransaction(); 954f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 95526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 956603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } finally { 95726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 958603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 959603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 960603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 96104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private void invalidateAuthTokenLocked(UserAccounts accounts, SQLiteDatabase db, 96204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani String accountType, String authToken) { 963ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana if (authToken == null || accountType == null) { 964ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana return; 965ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 9663326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana Cursor cursor = db.rawQuery( 9673326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana "SELECT " + TABLE_AUTHTOKENS + "." + AUTHTOKENS_ID 9683326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + ", " + TABLE_ACCOUNTS + "." + ACCOUNTS_NAME 9693326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + ", " + TABLE_AUTHTOKENS + "." + AUTHTOKENS_TYPE 9703326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + " FROM " + TABLE_ACCOUNTS 9713326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + " JOIN " + TABLE_AUTHTOKENS 9723326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + " ON " + TABLE_ACCOUNTS + "." + ACCOUNTS_ID 9733326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + " = " + AUTHTOKENS_ACCOUNTS_ID 9743326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + " WHERE " + AUTHTOKENS_AUTHTOKEN + " = ? AND " 9753326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + TABLE_ACCOUNTS + "." + ACCOUNTS_TYPE + " = ?", 9763326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana new String[]{authToken, accountType}); 9773326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana try { 9783326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana while (cursor.moveToNext()) { 9793326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana long authTokenId = cursor.getLong(0); 9803326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana String accountName = cursor.getString(1); 9813326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana String authTokenType = cursor.getString(2); 9823326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana db.delete(TABLE_AUTHTOKENS, AUTHTOKENS_ID + "=" + authTokenId, null); 98304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani writeAuthTokenIntoCacheLocked(accounts, db, new Account(accountName, accountType), 984f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana authTokenType, null); 985603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 9863326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } finally { 9873326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana cursor.close(); 988603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 989603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 990603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 99104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private boolean saveAuthTokenToDatabase(UserAccounts accounts, Account account, String type, 99204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani String authToken) { 99331957f1badbb900bbfe211317e1ea992d650a72dFred Quintana if (account == null || type == null) { 99431957f1badbb900bbfe211317e1ea992d650a72dFred Quintana return false; 99531957f1badbb900bbfe211317e1ea992d650a72dFred Quintana } 99650cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn cancelNotification(getSigninRequiredNotificationId(accounts, account), 99750cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn new UserHandle(accounts.userId)); 99804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 99904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getWritableDatabase(); 1000f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.beginTransaction(); 1001f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana try { 1002f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana long accountId = getAccountIdLocked(db, account); 1003f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (accountId < 0) { 1004f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return false; 1005f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 1006f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.delete(TABLE_AUTHTOKENS, 1007f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana AUTHTOKENS_ACCOUNTS_ID + "=" + accountId + " AND " + AUTHTOKENS_TYPE + "=?", 1008f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana new String[]{type}); 1009f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana ContentValues values = new ContentValues(); 1010f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana values.put(AUTHTOKENS_ACCOUNTS_ID, accountId); 1011f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana values.put(AUTHTOKENS_TYPE, type); 1012f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana values.put(AUTHTOKENS_AUTHTOKEN, authToken); 1013f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (db.insert(TABLE_AUTHTOKENS, AUTHTOKENS_AUTHTOKEN, values) >= 0) { 1014f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.setTransactionSuccessful(); 101504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani writeAuthTokenIntoCacheLocked(accounts, db, account, type, authToken); 1016f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return true; 1017f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 10183326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana return false; 1019f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } finally { 1020f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.endTransaction(); 10213326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 1022603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1023603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1024603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1025a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public String peekAuthToken(Account account, String authTokenType) { 102656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 102756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "peekAuthToken: " + account 102856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", authTokenType " + authTokenType 102956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 103056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 103156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 1032382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 1033382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null"); 1034d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkAuthenticateAccountsPermission(account); 103504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 103626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 103726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 103804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani return readAuthTokenInternal(accounts, account, authTokenType); 103926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 104026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 1041603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1042603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1043603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1044a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void setAuthToken(Account account, String authTokenType, String authToken) { 104556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 104656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "setAuthToken: " + account 104756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", authTokenType " + authTokenType 104856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 104956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 105056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 1051382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 1052382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null"); 1053d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkAuthenticateAccountsPermission(account); 105404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 105526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 105626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 105704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani saveAuthTokenToDatabase(accounts, account, authTokenType, authToken); 105826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 105926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 106026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1061603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1062603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1063a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void setPassword(Account account, String password) { 106456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 106556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "setAuthToken: " + account 106656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 106756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 106856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 1069382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 1070d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkAuthenticateAccountsPermission(account); 107104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 107226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 107326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 107404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani setPasswordInternal(accounts, account, password); 107526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 107626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 107726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1078603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1079603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 108004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private void setPasswordInternal(UserAccounts accounts, Account account, String password) { 108131957f1badbb900bbfe211317e1ea992d650a72dFred Quintana if (account == null) { 108231957f1badbb900bbfe211317e1ea992d650a72dFred Quintana return; 108331957f1badbb900bbfe211317e1ea992d650a72dFred Quintana } 108404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 108504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getWritableDatabase(); 1086f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.beginTransaction(); 1087f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana try { 1088f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana final ContentValues values = new ContentValues(); 1089f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana values.put(ACCOUNTS_PASSWORD, password); 1090f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana final long accountId = getAccountIdLocked(db, account); 1091f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (accountId >= 0) { 1092f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana final String[] argsAccountId = {String.valueOf(accountId)}; 1093f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.update(TABLE_ACCOUNTS, values, ACCOUNTS_ID + "=?", argsAccountId); 1094f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.delete(TABLE_AUTHTOKENS, AUTHTOKENS_ACCOUNTS_ID + "=?", argsAccountId); 109504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.authTokenCache.remove(account); 1096f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.setTransactionSuccessful(); 1097f5ffe89e736caee1419f0acb469565d5100b8fb8Costin Manolache } 1098f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } finally { 1099f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.endTransaction(); 1100d4a9d6c42bb412e27a8383aaacd051419d98a662Fred Quintana } 110104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani sendAccountsChangedBroadcast(accounts.userId); 1102d4a9d6c42bb412e27a8383aaacd051419d98a662Fred Quintana } 11033ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintana } 11043ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintana 110504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private void sendAccountsChangedBroadcast(int userId) { 110656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.i(TAG, "the accounts changed, sending broadcast of " 110756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ACCOUNTS_CHANGED_INTENT.getAction()); 110879af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn mContext.sendBroadcastAsUser(ACCOUNTS_CHANGED_INTENT, new UserHandle(userId)); 11093326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 11103326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 1111a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void clearPassword(Account account) { 111256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 111356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "clearPassword: " + account 111456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 111556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 111656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 1117382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 1118d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkManageAccountsPermission(); 111904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 112026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 112126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 112204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani setPasswordInternal(accounts, account, null); 112326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 112426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 112526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1126603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1127603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1128a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void setUserData(Account account, String key, String value) { 112956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 113056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "setUserData: " + account 113156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", key " + key 113256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 113356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 113456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 1135382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (key == null) throw new IllegalArgumentException("key is null"); 1136382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 1137d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkAuthenticateAccountsPermission(account); 113804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 113926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 1140603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana try { 114104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani setUserdataInternal(accounts, account, key, value); 1142ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } finally { 1143ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana restoreCallingIdentity(identityToken); 1144ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 1145ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 1146ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 114704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private void setUserdataInternal(UserAccounts accounts, Account account, String key, 114804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani String value) { 114931957f1badbb900bbfe211317e1ea992d650a72dFred Quintana if (account == null || key == null) { 115031957f1badbb900bbfe211317e1ea992d650a72dFred Quintana return; 115131957f1badbb900bbfe211317e1ea992d650a72dFred Quintana } 115204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 115304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getWritableDatabase(); 1154f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.beginTransaction(); 1155f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana try { 1156f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana long accountId = getAccountIdLocked(db, account); 1157f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (accountId < 0) { 1158ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana return; 115926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1160f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana long extrasId = getExtrasIdLocked(db, accountId, key); 1161f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (extrasId < 0 ) { 1162f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana extrasId = insertExtraLocked(db, accountId, key, value); 1163f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (extrasId < 0) { 1164f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return; 1165f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 1166f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } else { 1167f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana ContentValues values = new ContentValues(); 1168f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana values.put(EXTRAS_VALUE, value); 1169f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (1 != db.update(TABLE_EXTRAS, values, EXTRAS_ID + "=" + extrasId, null)) { 1170f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return; 1171f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 1172ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 1173f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 117404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani writeUserDataIntoCacheLocked(accounts, db, account, key, value); 1175f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.setTransactionSuccessful(); 1176f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } finally { 1177f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.endTransaction(); 1178603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1179603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1180603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1181603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1182d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private void onResult(IAccountManagerResponse response, Bundle result) { 118356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (result == null) { 118456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.e(TAG, "the result is unexpectedly null", new Exception()); 118556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 118656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 118756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, getClass().getSimpleName() + " calling onResult() on response " 118856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + response); 118956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 1190d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana try { 1191d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana response.onResult(result); 1192d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } catch (RemoteException e) { 1193d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana // if the caller is dead then there is no one to care about remote 1194d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana // exceptions 1195d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 1196d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Log.v(TAG, "failure while notifying response", e); 1197d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1198d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1199d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1200d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 1201d9640ec712806508877868d08aafaa2d715ff441Fred Quintana public void getAuthTokenLabel(IAccountManagerResponse response, final String accountType, 1202d9640ec712806508877868d08aafaa2d715ff441Fred Quintana final String authTokenType) 1203d9640ec712806508877868d08aafaa2d715ff441Fred Quintana throws RemoteException { 1204d9640ec712806508877868d08aafaa2d715ff441Fred Quintana if (accountType == null) throw new IllegalArgumentException("accountType is null"); 12055f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null"); 12065f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache 1207d9640ec712806508877868d08aafaa2d715ff441Fred Quintana final int callingUid = getCallingUid(); 1208d9640ec712806508877868d08aafaa2d715ff441Fred Quintana clearCallingIdentity(); 120927db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani if (callingUid != Process.SYSTEM_UID) { 1210d9640ec712806508877868d08aafaa2d715ff441Fred Quintana throw new SecurityException("can only call from system"); 1211d9640ec712806508877868d08aafaa2d715ff441Fred Quintana } 1212f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackborn UserAccounts accounts = getUserAccounts(UserHandle.getUserId(callingUid)); 12135f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache long identityToken = clearCallingIdentity(); 12145f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache try { 1215d9640ec712806508877868d08aafaa2d715ff441Fred Quintana new Session(accounts, response, accountType, false, 12165f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache false /* stripAuthTokenFromResult */) { 12175f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache protected String toDebugString(long now) { 12185f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache return super.toDebugString(now) + ", getAuthTokenLabel" 1219d9640ec712806508877868d08aafaa2d715ff441Fred Quintana + ", " + accountType 12205f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache + ", authTokenType " + authTokenType; 12215f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache } 12225f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache 12235f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache public void run() throws RemoteException { 12245f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache mAuthenticator.getAuthTokenLabel(this, authTokenType); 12255f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache } 12265f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache 12275f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache public void onResult(Bundle result) { 12285f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache if (result != null) { 12295f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache String label = result.getString(AccountManager.KEY_AUTH_TOKEN_LABEL); 12305f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache Bundle bundle = new Bundle(); 12315f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache bundle.putString(AccountManager.KEY_AUTH_TOKEN_LABEL, label); 12325f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache super.onResult(bundle); 12335f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache return; 12345f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache } else { 12355f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache super.onResult(result); 12365f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache } 12375f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache } 12385f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache }.bind(); 12395f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache } finally { 12405f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache restoreCallingIdentity(identityToken); 12415f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache } 12425f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache } 12435f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache 1244a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void getAuthToken(IAccountManagerResponse response, final Account account, 1245a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana final String authTokenType, final boolean notifyOnAuthFailure, 1246c6684f9e9790e92960504e9b32f20f27003d9f37Costin Manolache final boolean expectActivityLaunch, Bundle loginOptionsIn) { 124756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 124856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "getAuthToken: " + account 124956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", response " + response 125056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", authTokenType " + authTokenType 125156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", notifyOnAuthFailure " + notifyOnAuthFailure 125256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", expectActivityLaunch " + expectActivityLaunch 125356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 125456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 125556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 1256382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (response == null) throw new IllegalArgumentException("response is null"); 1257382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 1258382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null"); 1259d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkBinderPermission(Manifest.permission.USE_CREDENTIALS); 12604120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn final UserAccounts accounts = getUserAccountsForCaller(); 12616ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey final RegisteredServicesCache.ServiceInfo<AuthenticatorDescription> authenticatorInfo; 12626ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey authenticatorInfo = mAuthenticatorCache.getServiceInfo( 12636ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey AuthenticatorDescription.newKey(account.type), accounts.userId); 1264a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache final boolean customTokens = 1265a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache authenticatorInfo != null && authenticatorInfo.type.customTokens; 1266a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache 1267a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache // skip the check if customTokens 1268b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache final int callerUid = Binder.getCallingUid(); 1269a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache final boolean permissionGranted = customTokens || 1270a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache permissionIsGranted(account, authTokenType, callerUid); 1271a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache 1272c6684f9e9790e92960504e9b32f20f27003d9f37Costin Manolache final Bundle loginOptions = (loginOptionsIn == null) ? new Bundle() : 1273c6684f9e9790e92960504e9b32f20f27003d9f37Costin Manolache loginOptionsIn; 1274b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache // let authenticator know the identity of the caller 1275b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache loginOptions.putInt(AccountManager.KEY_CALLER_UID, callerUid); 1276b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache loginOptions.putInt(AccountManager.KEY_CALLER_PID, Binder.getCallingPid()); 1277b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache if (notifyOnAuthFailure) { 1278b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache loginOptions.putBoolean(AccountManager.KEY_NOTIFY_ON_FAILURE, true); 1279a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache } 12806ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey 128126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 128226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 1283d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana // if the caller has permission, do the peek. otherwise go the more expensive 1284d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana // route of starting a Session 1285a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache if (!customTokens && permissionGranted) { 128604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani String authToken = readAuthTokenInternal(accounts, account, authTokenType); 1287d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (authToken != null) { 128826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana Bundle result = new Bundle(); 1289f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana result.putString(AccountManager.KEY_AUTHTOKEN, authToken); 1290f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name); 1291f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana result.putString(AccountManager.KEY_ACCOUNT_TYPE, account.type); 1292d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana onResult(response, result); 1293d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana return; 1294a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1295a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1296603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 129704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani new Session(accounts, response, account.type, expectActivityLaunch, 12988570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana false /* stripAuthTokenFromResult */) { 129926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana protected String toDebugString(long now) { 130026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana if (loginOptions != null) loginOptions.keySet(); 130126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana return super.toDebugString(now) + ", getAuthToken" 130226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana + ", " + account 130326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana + ", authTokenType " + authTokenType 130426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana + ", loginOptions " + loginOptions 130526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana + ", notifyOnAuthFailure " + notifyOnAuthFailure; 130626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1307a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 130826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana public void run() throws RemoteException { 1309d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana // If the caller doesn't have permission then create and return the 1310d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana // "grant permission" intent instead of the "getAuthToken" intent. 1311d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (!permissionGranted) { 1312d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana mAuthenticator.getAuthTokenLabel(this, authTokenType); 1313d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } else { 1314d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana mAuthenticator.getAuthToken(this, account, authTokenType, loginOptions); 1315d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 131626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1317a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 131826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana public void onResult(Bundle result) { 131926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana if (result != null) { 1320f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana if (result.containsKey(AccountManager.KEY_AUTH_TOKEN_LABEL)) { 1321d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Intent intent = newGrantCredentialsPermissionIntent(account, callerUid, 1322d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana new AccountAuthenticatorResponse(this), 1323d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana authTokenType, 1324f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana result.getString(AccountManager.KEY_AUTH_TOKEN_LABEL)); 1325d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Bundle bundle = new Bundle(); 1326f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana bundle.putParcelable(AccountManager.KEY_INTENT, intent); 1327d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana onResult(bundle); 1328d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana return; 1329d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1330f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana String authToken = result.getString(AccountManager.KEY_AUTHTOKEN); 133126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana if (authToken != null) { 1332f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana String name = result.getString(AccountManager.KEY_ACCOUNT_NAME); 1333f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana String type = result.getString(AccountManager.KEY_ACCOUNT_TYPE); 133426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana if (TextUtils.isEmpty(type) || TextUtils.isEmpty(name)) { 1335f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana onError(AccountManager.ERROR_CODE_INVALID_RESPONSE, 133626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana "the type and name should not be empty"); 133726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana return; 133826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1339a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache if (!customTokens) { 134004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani saveAuthTokenToDatabase(mAccounts, new Account(name, type), 1341a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache authTokenType, authToken); 1342a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache } 1343a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1344603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1345f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana Intent intent = result.getParcelable(AccountManager.KEY_INTENT); 1346d606045070dcf6a011e49a7711d2f17d8f2de8c1Costin Manolache if (intent != null && notifyOnAuthFailure && !customTokens) { 134704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani doNotification(mAccounts, 1348f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana account, result.getString(AccountManager.KEY_AUTH_FAILED_MESSAGE), 13494120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn intent, accounts.userId); 135026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1351a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 135226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana super.onResult(result); 1353a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 135426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana }.bind(); 135526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 135626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 135726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1358603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1359603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 13604120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn private void createNoCredentialsPermissionNotification(Account account, Intent intent, 13614120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn int userId) { 1362d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana int uid = intent.getIntExtra( 1363d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana GrantCredentialsPermissionActivity.EXTRAS_REQUESTING_UID, -1); 1364d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana String authTokenType = intent.getStringExtra( 1365d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana GrantCredentialsPermissionActivity.EXTRAS_AUTH_TOKEN_TYPE); 1366d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana String authTokenLabel = intent.getStringExtra( 1367d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana GrantCredentialsPermissionActivity.EXTRAS_AUTH_TOKEN_LABEL); 1368d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 1369d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Notification n = new Notification(android.R.drawable.stat_sys_warning, null, 1370d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 0 /* when */); 1371ee452ee5359cdfa3c3fbf6783722d3aaa2ec5ca6Eric Fischer final String titleAndSubtitle = 1372ee452ee5359cdfa3c3fbf6783722d3aaa2ec5ca6Eric Fischer mContext.getString(R.string.permission_request_notification_with_subtitle, 1373ee452ee5359cdfa3c3fbf6783722d3aaa2ec5ca6Eric Fischer account.name); 1374ee452ee5359cdfa3c3fbf6783722d3aaa2ec5ca6Eric Fischer final int index = titleAndSubtitle.indexOf('\n'); 137585e7279d9cc1ee8e4dd1f993a9e61a9eb547ecbcCostin Manolache String title = titleAndSubtitle; 137685e7279d9cc1ee8e4dd1f993a9e61a9eb547ecbcCostin Manolache String subtitle = ""; 137785e7279d9cc1ee8e4dd1f993a9e61a9eb547ecbcCostin Manolache if (index > 0) { 137885e7279d9cc1ee8e4dd1f993a9e61a9eb547ecbcCostin Manolache title = titleAndSubtitle.substring(0, index); 1379a12fccf57d5ec289793699d9b22ff45daccd3933Maggie Benthall subtitle = titleAndSubtitle.substring(index + 1); 138085e7279d9cc1ee8e4dd1f993a9e61a9eb547ecbcCostin Manolache } 138150cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn UserHandle user = new UserHandle(userId); 13824120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn n.setLatestEventInfo(mContext, title, subtitle, 13834120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn PendingIntent.getActivityAsUser(mContext, 0, intent, 138450cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn PendingIntent.FLAG_CANCEL_CURRENT, null, user)); 138550cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn installNotification(getCredentialPermissionNotificationId( 138650cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn account, authTokenType, uid), n, user); 1387d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1388d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 13895f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache private Intent newGrantCredentialsPermissionIntent(Account account, int uid, 13905f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache AccountAuthenticatorResponse response, String authTokenType, String authTokenLabel) { 1391d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 1392d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Intent intent = new Intent(mContext, GrantCredentialsPermissionActivity.class); 139346703b099516c383a6882815bcf9cd4df0ec538dBrian Carlstrom // See FLAG_ACTIVITY_NEW_TASK docs for limitations and benefits of the flag. 13949ec17366c17efd14c643ee88fa1132ab05197349Costin Manolache // Since it was set in Eclair+ we can't change it without breaking apps using 13959ec17366c17efd14c643ee88fa1132ab05197349Costin Manolache // the intent from a non-Activity context. 13969ec17366c17efd14c643ee88fa1132ab05197349Costin Manolache intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 1397d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana intent.addCategory( 1398d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana String.valueOf(getCredentialPermissionNotificationId(account, authTokenType, uid))); 13995f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache 1400d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana intent.putExtra(GrantCredentialsPermissionActivity.EXTRAS_ACCOUNT, account); 1401d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana intent.putExtra(GrantCredentialsPermissionActivity.EXTRAS_AUTH_TOKEN_TYPE, authTokenType); 1402d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana intent.putExtra(GrantCredentialsPermissionActivity.EXTRAS_RESPONSE, response); 1403d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana intent.putExtra(GrantCredentialsPermissionActivity.EXTRAS_REQUESTING_UID, uid); 14045f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache 1405d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana return intent; 1406d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1407d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 1408d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private Integer getCredentialPermissionNotificationId(Account account, String authTokenType, 1409d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana int uid) { 1410d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Integer id; 1411f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackborn UserAccounts accounts = getUserAccounts(UserHandle.getUserId(uid)); 141204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.credentialsPermissionNotificationIds) { 1413d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana final Pair<Pair<Account, String>, Integer> key = 1414d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana new Pair<Pair<Account, String>, Integer>( 1415d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana new Pair<Account, String>(account, authTokenType), uid); 141604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani id = accounts.credentialsPermissionNotificationIds.get(key); 1417d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (id == null) { 1418d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana id = mNotificationIds.incrementAndGet(); 141904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.credentialsPermissionNotificationIds.put(key, id); 1420d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1421d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1422d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana return id; 1423d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1424d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 142504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private Integer getSigninRequiredNotificationId(UserAccounts accounts, Account account) { 1426d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Integer id; 142704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.signinRequiredNotificationIds) { 142804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani id = accounts.signinRequiredNotificationIds.get(account); 1429d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (id == null) { 1430d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana id = mNotificationIds.incrementAndGet(); 143104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.signinRequiredNotificationIds.put(account, id); 1432d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1433d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1434d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana return id; 1435d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1436d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 143727db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani public void addAccount(final IAccountManagerResponse response, final String accountType, 14383326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana final String authTokenType, final String[] requiredFeatures, 1439b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache final boolean expectActivityLaunch, final Bundle optionsIn) { 144056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 144156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "addAccount: accountType " + accountType 144256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", response " + response 144356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", authTokenType " + authTokenType 144456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", requiredFeatures " + stringArrayToString(requiredFeatures) 144556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", expectActivityLaunch " + expectActivityLaunch 144656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 144756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 144856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 1449382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (response == null) throw new IllegalArgumentException("response is null"); 1450382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (accountType == null) throw new IllegalArgumentException("accountType is null"); 1451d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkManageAccountsPermission(); 1452b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache 145371e6c697e54a43d357cc25d87a446d140f17396aAmith Yamasani // Is user disallowed from modifying accounts? 145427db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani if (!canUserModifyAccounts(Binder.getCallingUid())) { 1455df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani try { 1456df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani response.onError(AccountManager.ERROR_CODE_USER_RESTRICTED, 1457df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani "User is not allowed to add an account!"); 1458df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani } catch (RemoteException re) { 1459df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani } 146023c8b96a7e5c3f4c169bf65ae3886357943bb7b0Amith Yamasani Intent cantAddAccount = new Intent(mContext, CantAddAccountActivity.class); 146123c8b96a7e5c3f4c169bf65ae3886357943bb7b0Amith Yamasani cantAddAccount.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 146223c8b96a7e5c3f4c169bf65ae3886357943bb7b0Amith Yamasani long identityToken = clearCallingIdentity(); 146323c8b96a7e5c3f4c169bf65ae3886357943bb7b0Amith Yamasani try { 146423c8b96a7e5c3f4c169bf65ae3886357943bb7b0Amith Yamasani mContext.startActivityAsUser(cantAddAccount, UserHandle.CURRENT); 146523c8b96a7e5c3f4c169bf65ae3886357943bb7b0Amith Yamasani } finally { 146623c8b96a7e5c3f4c169bf65ae3886357943bb7b0Amith Yamasani restoreCallingIdentity(identityToken); 146723c8b96a7e5c3f4c169bf65ae3886357943bb7b0Amith Yamasani } 1468df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani return; 1469df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani } 1470df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani 147104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 1472b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache final int pid = Binder.getCallingPid(); 1473b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache final int uid = Binder.getCallingUid(); 1474b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache final Bundle options = (optionsIn == null) ? new Bundle() : optionsIn; 1475b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache options.putInt(AccountManager.KEY_CALLER_UID, uid); 1476b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache options.putInt(AccountManager.KEY_CALLER_PID, pid); 1477b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache 147826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 147926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 148004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani new Session(accounts, response, accountType, expectActivityLaunch, 14818570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana true /* stripAuthTokenFromResult */) { 148226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana public void run() throws RemoteException { 14833348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache mAuthenticator.addAccount(this, mAccountType, authTokenType, requiredFeatures, 14843326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana options); 148526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1486a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 148726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana protected String toDebugString(long now) { 148826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana return super.toDebugString(now) + ", addAccount" 14893326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + ", accountType " + accountType 14903326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + ", requiredFeatures " 14913326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + (requiredFeatures != null 14923326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana ? TextUtils.join(",", requiredFeatures) 14933326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana : null); 149426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 149526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana }.bind(); 149626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 149726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 149826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1499603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1500603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 15012c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani @Override 15022c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani public void confirmCredentialsAsUser(IAccountManagerResponse response, 15032c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani final Account account, final Bundle options, final boolean expectActivityLaunch, 15042c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani int userId) { 15052c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani // Only allow the system process to read accounts of other users 15062c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani if (userId != UserHandle.getCallingUserId() 150727db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani && Binder.getCallingUid() != Process.myUid()) { 15082c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani throw new SecurityException("User " + UserHandle.getCallingUserId() 15092c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani + " trying to confirm account credentials for " + userId); 15102c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani } 15112c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani 151256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 151356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "confirmCredentials: " + account 151456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", response " + response 151556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", expectActivityLaunch " + expectActivityLaunch 151656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 151756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 151856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 1519382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (response == null) throw new IllegalArgumentException("response is null"); 1520382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 1521d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkManageAccountsPermission(); 15222c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani UserAccounts accounts = getUserAccounts(userId); 152326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 152426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 152504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani new Session(accounts, response, account.type, expectActivityLaunch, 15268570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana true /* stripAuthTokenFromResult */) { 152726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana public void run() throws RemoteException { 1528f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana mAuthenticator.confirmCredentials(this, account, options); 152926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 153026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana protected String toDebugString(long now) { 153126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana return super.toDebugString(now) + ", confirmCredentials" 153226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana + ", " + account; 153326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 153426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana }.bind(); 153526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 153626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 153726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1538603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1539603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1540a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void updateCredentials(IAccountManagerResponse response, final Account account, 1541a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana final String authTokenType, final boolean expectActivityLaunch, 1542a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana final Bundle loginOptions) { 154356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 154456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "updateCredentials: " + account 154556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", response " + response 154656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", authTokenType " + authTokenType 154756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", expectActivityLaunch " + expectActivityLaunch 154856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 154956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 155056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 1551382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (response == null) throw new IllegalArgumentException("response is null"); 1552382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 1553382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null"); 1554d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkManageAccountsPermission(); 155504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 155626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 155726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 155804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani new Session(accounts, response, account.type, expectActivityLaunch, 15598570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana true /* stripAuthTokenFromResult */) { 156026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana public void run() throws RemoteException { 156126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana mAuthenticator.updateCredentials(this, account, authTokenType, loginOptions); 156226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 156326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana protected String toDebugString(long now) { 156426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana if (loginOptions != null) loginOptions.keySet(); 156526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana return super.toDebugString(now) + ", updateCredentials" 156626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana + ", " + account 156726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana + ", authTokenType " + authTokenType 156826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana + ", loginOptions " + loginOptions; 156926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 157026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana }.bind(); 157126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 157226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 157326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1574603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1575603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1576a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void editProperties(IAccountManagerResponse response, final String accountType, 1577a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana final boolean expectActivityLaunch) { 157856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 157956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "editProperties: accountType " + accountType 158056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", response " + response 158156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", expectActivityLaunch " + expectActivityLaunch 158256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 158356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 158456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 1585382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (response == null) throw new IllegalArgumentException("response is null"); 1586382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (accountType == null) throw new IllegalArgumentException("accountType is null"); 1587d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkManageAccountsPermission(); 158804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 158926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 159026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 159104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani new Session(accounts, response, accountType, expectActivityLaunch, 15928570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana true /* stripAuthTokenFromResult */) { 159326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana public void run() throws RemoteException { 159426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana mAuthenticator.editProperties(this, mAccountType); 159526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 159626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana protected String toDebugString(long now) { 159726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana return super.toDebugString(now) + ", editProperties" 159826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana + ", accountType " + accountType; 159926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 160026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana }.bind(); 160126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 160226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 160326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1604603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1605603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 16063326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana private class GetAccountsByTypeAndFeatureSession extends Session { 16073326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana private final String[] mFeatures; 16083326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana private volatile Account[] mAccountsOfType = null; 16093326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana private volatile ArrayList<Account> mAccountsWithFeatures = null; 16103326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana private volatile int mCurrentAccount = 0; 1611df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani private int mCallingUid; 16123326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 161304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani public GetAccountsByTypeAndFeatureSession(UserAccounts accounts, 1614df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani IAccountManagerResponse response, String type, String[] features, int callingUid) { 161504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani super(accounts, response, type, false /* expectActivityLaunch */, 16168570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana true /* stripAuthTokenFromResult */); 1617df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani mCallingUid = callingUid; 16183326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana mFeatures = features; 16193326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 16203326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 16213326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana public void run() throws RemoteException { 162204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (mAccounts.cacheLock) { 162327db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani mAccountsOfType = getAccountsFromCacheLocked(mAccounts, mAccountType, mCallingUid, 162427db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani null); 1625f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 16263326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana // check whether each account matches the requested features 16273326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana mAccountsWithFeatures = new ArrayList<Account>(mAccountsOfType.length); 16283326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana mCurrentAccount = 0; 16293326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 16303326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana checkAccount(); 16313326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 16323326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 16333326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana public void checkAccount() { 16343326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana if (mCurrentAccount >= mAccountsOfType.length) { 16353326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana sendResult(); 16363326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana return; 16373326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 16383326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 163929e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana final IAccountAuthenticator accountAuthenticator = mAuthenticator; 164029e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana if (accountAuthenticator == null) { 164129e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana // It is possible that the authenticator has died, which is indicated by 164229e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana // mAuthenticator being set to null. If this happens then just abort. 164329e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana // There is no need to send back a result or error in this case since 164429e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana // that already happened when mAuthenticator was cleared. 164529e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 164629e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana Log.v(TAG, "checkAccount: aborting session since we are no longer" 164729e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana + " connected to the authenticator, " + toDebugString()); 164829e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana } 164929e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana return; 165029e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana } 16513326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana try { 165229e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana accountAuthenticator.hasFeatures(this, mAccountsOfType[mCurrentAccount], mFeatures); 16533326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } catch (RemoteException e) { 1654f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana onError(AccountManager.ERROR_CODE_REMOTE_EXCEPTION, "remote exception"); 1655a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1656603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1657603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 16583326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana public void onResult(Bundle result) { 16593326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana mNumResults++; 16603326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana if (result == null) { 1661f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana onError(AccountManager.ERROR_CODE_INVALID_RESPONSE, "null bundle"); 16623326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana return; 16633326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 1664f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana if (result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT, false)) { 16653326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana mAccountsWithFeatures.add(mAccountsOfType[mCurrentAccount]); 16663326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 16673326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana mCurrentAccount++; 16683326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana checkAccount(); 1669a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 16703326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 16713326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana public void sendResult() { 16723326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana IAccountManagerResponse response = getResponseAndClose(); 16733326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana if (response != null) { 16743326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana try { 16753326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana Account[] accounts = new Account[mAccountsWithFeatures.size()]; 16763326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana for (int i = 0; i < accounts.length; i++) { 16773326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana accounts[i] = mAccountsWithFeatures.get(i); 16783326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 167956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 168056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, getClass().getSimpleName() + " calling onResult() on response " 168156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + response); 168256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 16833326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana Bundle result = new Bundle(); 1684f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana result.putParcelableArray(AccountManager.KEY_ACCOUNTS, accounts); 16853326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana response.onResult(result); 16863326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } catch (RemoteException e) { 16873326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana // if the caller is dead then there is no one to care about remote exceptions 16883326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 16893326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana Log.v(TAG, "failure while notifying response", e); 16903326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 16913326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 16923326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 16933326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 16943326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 16953326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 16963326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana protected String toDebugString(long now) { 16973326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana return super.toDebugString(now) + ", getAccountsByTypeAndFeatures" 16983326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + ", " + (mFeatures != null ? TextUtils.join(",", mFeatures) : null); 16993326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 17003326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 1701ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 170204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani /** 170304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani * Returns the accounts for a specific user 170404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani * @hide 170504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani */ 170604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani public Account[] getAccounts(int userId) { 170704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani checkReadAccountsPermission(); 170804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccounts(userId); 1709df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani int callingUid = Binder.getCallingUid(); 171004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani long identityToken = clearCallingIdentity(); 171104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani try { 171204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 171327db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani return getAccountsFromCacheLocked(accounts, null, callingUid, null); 171404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 171504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } finally { 171604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani restoreCallingIdentity(identityToken); 171704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 171804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 171904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani 1720f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani /** 17216ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey * Returns accounts for all running users. 17226ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey * 1723f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani * @hide 1724f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani */ 17256ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey public AccountAndUser[] getRunningAccounts() { 17266ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey final int[] runningUserIds; 17276ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey try { 17286ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey runningUserIds = ActivityManagerNative.getDefault().getRunningUserIds(); 17296ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey } catch (RemoteException e) { 17306ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey // Running in system_server; should never happen 17316ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey throw new RuntimeException(e); 17326ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey } 17336eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey return getAccounts(runningUserIds); 17346eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey } 17356eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey 17366eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey /** {@hide} */ 17376eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey public AccountAndUser[] getAllAccounts() { 17386eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey final List<UserInfo> users = getUserManager().getUsers(); 17396eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey final int[] userIds = new int[users.size()]; 17406eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey for (int i = 0; i < userIds.length; i++) { 17416eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey userIds[i] = users.get(i).id; 17426eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey } 17436eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey return getAccounts(userIds); 17446eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey } 17456ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey 17466eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey private AccountAndUser[] getAccounts(int[] userIds) { 17476ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey final ArrayList<AccountAndUser> runningAccounts = Lists.newArrayList(); 17486ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey synchronized (mUsers) { 17496eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey for (int userId : userIds) { 17506ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey UserAccounts userAccounts = getUserAccounts(userId); 1751f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani if (userAccounts == null) continue; 1752f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani synchronized (userAccounts.cacheLock) { 1753df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani Account[] accounts = getAccountsFromCacheLocked(userAccounts, null, 175427db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani Binder.getCallingUid(), null); 1755f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani for (int a = 0; a < accounts.length; a++) { 17566ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey runningAccounts.add(new AccountAndUser(accounts[a], userId)); 1757f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani } 1758f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani } 1759f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani } 1760f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani } 17616ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey 17626ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey AccountAndUser[] accountsArray = new AccountAndUser[runningAccounts.size()]; 17636ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey return runningAccounts.toArray(accountsArray); 1764f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani } 1765f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani 17662c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani @Override 17672c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani public Account[] getAccountsAsUser(String type, int userId) { 176827db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani return getAccountsAsUser(type, userId, null, -1); 176927db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani } 177027db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani 177127db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani private Account[] getAccountsAsUser(String type, int userId, String callingPackage, 177227db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani int packageUid) { 177327db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani int callingUid = Binder.getCallingUid(); 17742c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani // Only allow the system process to read accounts of other users 17752c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani if (userId != UserHandle.getCallingUserId() 177627db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani && callingUid != Process.myUid()) { 17772c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani throw new SecurityException("User " + UserHandle.getCallingUserId() 17782c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani + " trying to get account for " + userId); 17792c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani } 17802c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani 178156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 178256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "getAccounts: accountType " + type 178356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 178456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 178556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 178627db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani // If the original calling app was using the framework account chooser activity, we'll 178727db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani // be passed in the original caller's uid here, which is what should be used for filtering. 178827db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani if (packageUid != -1 && UserHandle.isSameApp(callingUid, Process.myUid())) { 178927db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani callingUid = packageUid; 179027db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani } 1791ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana checkReadAccountsPermission(); 17922c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani UserAccounts accounts = getUserAccounts(userId); 1793ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana long identityToken = clearCallingIdentity(); 1794ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana try { 179504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 179627db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani return getAccountsFromCacheLocked(accounts, type, callingUid, callingPackage); 1797f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 1798ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } finally { 1799ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana restoreCallingIdentity(identityToken); 1800ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 1801ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 1802ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 18032c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani @Override 180467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani public boolean addSharedAccountAsUser(Account account, int userId) { 180567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani userId = handleIncomingUser(userId); 180667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani SQLiteDatabase db = getUserAccounts(userId).openHelper.getWritableDatabase(); 180767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani ContentValues values = new ContentValues(); 180867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani values.put(ACCOUNTS_NAME, account.name); 180967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani values.put(ACCOUNTS_TYPE, account.type); 181067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani db.delete(TABLE_SHARED_ACCOUNTS, ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?", 181167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani new String[] {account.name, account.type}); 181267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani long accountId = db.insert(TABLE_SHARED_ACCOUNTS, ACCOUNTS_NAME, values); 181367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani if (accountId < 0) { 181467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani Log.w(TAG, "insertAccountIntoDatabase: " + account 181567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani + ", skipping the DB insert failed"); 181667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani return false; 181767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 181867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani return true; 181967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 182067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani 182167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani @Override 182267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani public boolean removeSharedAccountAsUser(Account account, int userId) { 182367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani userId = handleIncomingUser(userId); 182467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani UserAccounts accounts = getUserAccounts(userId); 182567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani SQLiteDatabase db = accounts.openHelper.getWritableDatabase(); 182667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani int r = db.delete(TABLE_SHARED_ACCOUNTS, ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?", 182767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani new String[] {account.name, account.type}); 182867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani if (r > 0) { 182967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani removeAccountInternal(accounts, account); 183067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 183167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani return r > 0; 183267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 183367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani 183467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani @Override 183567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani public Account[] getSharedAccountsAsUser(int userId) { 183667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani userId = handleIncomingUser(userId); 183767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani UserAccounts accounts = getUserAccounts(userId); 183867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani ArrayList<Account> accountList = new ArrayList<Account>(); 183967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani Cursor cursor = null; 184067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani try { 184167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani cursor = accounts.openHelper.getReadableDatabase() 184267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani .query(TABLE_SHARED_ACCOUNTS, new String[]{ACCOUNTS_NAME, ACCOUNTS_TYPE}, 184367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani null, null, null, null, null); 184467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani if (cursor != null && cursor.moveToFirst()) { 184567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani int nameIndex = cursor.getColumnIndex(ACCOUNTS_NAME); 184667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani int typeIndex = cursor.getColumnIndex(ACCOUNTS_TYPE); 184767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani do { 184867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani accountList.add(new Account(cursor.getString(nameIndex), 184967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani cursor.getString(typeIndex))); 185067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } while (cursor.moveToNext()); 185167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 185267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } finally { 185367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani if (cursor != null) { 185467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani cursor.close(); 185567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 185667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 185767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani Account[] accountArray = new Account[accountList.size()]; 185867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani accountList.toArray(accountArray); 185967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani return accountArray; 186067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 186167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani 186267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani @Override 18632c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani public Account[] getAccounts(String type) { 18642c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani return getAccountsAsUser(type, UserHandle.getCallingUserId()); 18652c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani } 18662c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani 186727db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani @Override 186827db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani public Account[] getAccountsForPackage(String packageName, int uid) { 186927db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani int callingUid = Binder.getCallingUid(); 187027db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani if (!UserHandle.isSameApp(callingUid, Process.myUid())) { 187127db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani throw new SecurityException("getAccountsForPackage() called from unauthorized uid " 187227db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani + callingUid + " with uid=" + uid); 187327db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani } 187427db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani return getAccountsAsUser(null, UserHandle.getCallingUserId(), packageName, uid); 187527db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani } 187627db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani 1877ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana public void getAccountsByFeatures(IAccountManagerResponse response, 18783326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana String type, String[] features) { 187956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 188056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "getAccounts: accountType " + type 188156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", response " + response 188256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", features " + stringArrayToString(features) 188356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 188456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 188556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 1886382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (response == null) throw new IllegalArgumentException("response is null"); 1887382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (type == null) throw new IllegalArgumentException("accountType is null"); 1888d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkReadAccountsPermission(); 188904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts userAccounts = getUserAccountsForCaller(); 1890df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani int callingUid = Binder.getCallingUid(); 18913326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana long identityToken = clearCallingIdentity(); 18923326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana try { 1893ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana if (features == null || features.length == 0) { 1894f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana Account[] accounts; 189504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (userAccounts.cacheLock) { 189627db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani accounts = getAccountsFromCacheLocked(userAccounts, type, callingUid, null); 1897f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 1898d4a9d6c42bb412e27a8383aaacd051419d98a662Fred Quintana Bundle result = new Bundle(); 1899d4a9d6c42bb412e27a8383aaacd051419d98a662Fred Quintana result.putParcelableArray(AccountManager.KEY_ACCOUNTS, accounts); 1900d4a9d6c42bb412e27a8383aaacd051419d98a662Fred Quintana onResult(response, result); 1901ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana return; 1902ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 1903df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani new GetAccountsByTypeAndFeatureSession(userAccounts, response, type, features, 1904df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani callingUid).bind(); 19053326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } finally { 19063326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana restoreCallingIdentity(identityToken); 19073326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 19083326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 19093326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 1910f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana private long getAccountIdLocked(SQLiteDatabase db, Account account) { 1911603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana Cursor cursor = db.query(TABLE_ACCOUNTS, new String[]{ACCOUNTS_ID}, 1912ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana "name=? AND type=?", new String[]{account.name, account.type}, null, null, null); 1913603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana try { 1914603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana if (cursor.moveToNext()) { 1915603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana return cursor.getLong(0); 1916603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1917603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana return -1; 1918603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } finally { 1919603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana cursor.close(); 1920603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1921603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1922603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1923f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana private long getExtrasIdLocked(SQLiteDatabase db, long accountId, String key) { 1924603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana Cursor cursor = db.query(TABLE_EXTRAS, new String[]{EXTRAS_ID}, 1925603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana EXTRAS_ACCOUNTS_ID + "=" + accountId + " AND " + EXTRAS_KEY + "=?", 1926603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana new String[]{key}, null, null, null); 1927603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana try { 1928603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana if (cursor.moveToNext()) { 1929603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana return cursor.getLong(0); 1930603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1931603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana return -1; 1932603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } finally { 1933603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana cursor.close(); 1934603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1935603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1936603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1937a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana private abstract class Session extends IAccountAuthenticatorResponse.Stub 1938b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana implements IBinder.DeathRecipient, ServiceConnection { 1939603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana IAccountManagerResponse mResponse; 1940603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana final String mAccountType; 1941a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana final boolean mExpectActivityLaunch; 1942a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana final long mCreationTime; 1943a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 19443326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana public int mNumResults = 0; 1945a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana private int mNumRequestContinued = 0; 1946a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana private int mNumErrors = 0; 1947a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 1948603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana IAccountAuthenticator mAuthenticator = null; 1949603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 19508570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana private final boolean mStripAuthTokenFromResult; 195104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani protected final UserAccounts mAccounts; 19528570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana 195304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani public Session(UserAccounts accounts, IAccountManagerResponse response, String accountType, 19548570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana boolean expectActivityLaunch, boolean stripAuthTokenFromResult) { 1955603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana super(); 195667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani //if (response == null) throw new IllegalArgumentException("response is null"); 19573326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana if (accountType == null) throw new IllegalArgumentException("accountType is null"); 195804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani mAccounts = accounts; 19598570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana mStripAuthTokenFromResult = stripAuthTokenFromResult; 1960603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mResponse = response; 1961603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mAccountType = accountType; 1962a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana mExpectActivityLaunch = expectActivityLaunch; 1963a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana mCreationTime = SystemClock.elapsedRealtime(); 1964a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana synchronized (mSessions) { 1965a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana mSessions.put(toString(), this); 1966a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 196767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani if (response != null) { 196867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani try { 196967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani response.asBinder().linkToDeath(this, 0 /* flags */); 197067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } catch (RemoteException e) { 197167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani mResponse = null; 197267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani binderDied(); 197367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 1974a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1975603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1976603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1977a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana IAccountManagerResponse getResponseAndClose() { 1978603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana if (mResponse == null) { 1979603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana // this session has already been closed 1980603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana return null; 1981603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1982a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana IAccountManagerResponse response = mResponse; 1983a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana close(); // this clears mResponse so we need to save the response before this call 1984a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana return response; 1985a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1986a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 1987a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana private void close() { 1988a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana synchronized (mSessions) { 1989a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (mSessions.remove(toString()) == null) { 1990a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana // the session was already closed, so bail out now 1991a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana return; 1992a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1993a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1994a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (mResponse != null) { 1995a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana // stop listening for response deaths 1996a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana mResponse.asBinder().unlinkToDeath(this, 0 /* flags */); 1997a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 1998a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana // clear this so that we don't accidentally send any further results 1999a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana mResponse = null; 2000a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 2001603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana cancelTimeout(); 2002603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana unbind(); 2003a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 2004a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 2005a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void binderDied() { 2006603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mResponse = null; 2007a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana close(); 2008a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 2009a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 2010a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana protected String toDebugString() { 2011a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana return toDebugString(SystemClock.elapsedRealtime()); 2012a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 2013a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 2014a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana protected String toDebugString(long now) { 2015a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana return "Session: expectLaunch " + mExpectActivityLaunch 2016a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + ", connected " + (mAuthenticator != null) 2017a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + ", stats (" + mNumResults + "/" + mNumRequestContinued 2018a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + "/" + mNumErrors + ")" 2019a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + ", lifetime " + ((now - mCreationTime) / 1000.0); 2020603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2021603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 2022603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana void bind() { 2023a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 2024a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana Log.v(TAG, "initiating bind to authenticator type " + mAccountType); 2025a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 2026b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana if (!bindToAuthenticator(mAccountType)) { 2027a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana Log.d(TAG, "bind attempt failed for " + toDebugString()); 2028f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana onError(AccountManager.ERROR_CODE_REMOTE_EXCEPTION, "bind failure"); 2029603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2030603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2031603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 2032603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private void unbind() { 2033603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana if (mAuthenticator != null) { 2034603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mAuthenticator = null; 2035b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana mContext.unbindService(this); 2036603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2037603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2038603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 2039603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public void scheduleTimeout() { 2040603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mMessageHandler.sendMessageDelayed( 2041603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mMessageHandler.obtainMessage(MESSAGE_TIMED_OUT, this), TIMEOUT_DELAY_MS); 2042603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2043603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 2044603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public void cancelTimeout() { 2045603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mMessageHandler.removeMessages(MESSAGE_TIMED_OUT, this); 2046603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2047603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 2048b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana public void onServiceConnected(ComponentName name, IBinder service) { 2049603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mAuthenticator = IAccountAuthenticator.Stub.asInterface(service); 2050a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana try { 2051a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana run(); 2052a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } catch (RemoteException e) { 2053f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana onError(AccountManager.ERROR_CODE_REMOTE_EXCEPTION, 2054a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana "remote exception"); 2055a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 2056603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2057603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 2058b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana public void onServiceDisconnected(ComponentName name) { 2059a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana mAuthenticator = null; 2060a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana IAccountManagerResponse response = getResponseAndClose(); 2061603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana if (response != null) { 2062166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana try { 2063166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana response.onError(AccountManager.ERROR_CODE_REMOTE_EXCEPTION, 2064166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana "disconnected"); 2065166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana } catch (RemoteException e) { 2066166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 2067166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana Log.v(TAG, "Session.onServiceDisconnected: " 2068166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana + "caught RemoteException while responding", e); 2069166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana } 2070166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana } 2071603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2072603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2073603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 2074b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana public abstract void run() throws RemoteException; 2075b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana 2076603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public void onTimedOut() { 2077a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana IAccountManagerResponse response = getResponseAndClose(); 2078603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana if (response != null) { 2079166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana try { 2080166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana response.onError(AccountManager.ERROR_CODE_REMOTE_EXCEPTION, 2081166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana "timeout"); 2082166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana } catch (RemoteException e) { 2083166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 2084166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana Log.v(TAG, "Session.onTimedOut: caught RemoteException while responding", 2085166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana e); 2086166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana } 2087166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana } 2088603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2089603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2090603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 2091a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void onResult(Bundle result) { 2092a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana mNumResults++; 2093f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana if (result != null && !TextUtils.isEmpty(result.getString(AccountManager.KEY_AUTHTOKEN))) { 2094f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana String accountName = result.getString(AccountManager.KEY_ACCOUNT_NAME); 2095f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana String accountType = result.getString(AccountManager.KEY_ACCOUNT_TYPE); 2096d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (!TextUtils.isEmpty(accountName) && !TextUtils.isEmpty(accountType)) { 2097d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Account account = new Account(accountName, accountType); 209850cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn cancelNotification(getSigninRequiredNotificationId(mAccounts, account), 209950cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn new UserHandle(mAccounts.userId)); 2100d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2101603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2102a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana IAccountManagerResponse response; 2103a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (mExpectActivityLaunch && result != null 2104f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana && result.containsKey(AccountManager.KEY_INTENT)) { 2105a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana response = mResponse; 2106a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } else { 2107a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana response = getResponseAndClose(); 2108603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2109603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana if (response != null) { 2110603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana try { 2111a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (result == null) { 211256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 211356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, getClass().getSimpleName() 211456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + " calling onError() on response " + response); 211556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 2116f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana response.onError(AccountManager.ERROR_CODE_INVALID_RESPONSE, 2117a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana "null bundle returned"); 2118a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } else { 21198570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana if (mStripAuthTokenFromResult) { 21208570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana result.remove(AccountManager.KEY_AUTHTOKEN); 21218570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana } 212256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 212356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, getClass().getSimpleName() 212456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + " calling onResult() on response " + response); 212556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 2126a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana response.onResult(result); 2127a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 2128603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } catch (RemoteException e) { 2129a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana // if the caller is dead then there is no one to care about remote exceptions 2130a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 2131a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana Log.v(TAG, "failure while notifying response", e); 2132a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 2133603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2134603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2135603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2136603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 2137a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void onRequestContinued() { 2138a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana mNumRequestContinued++; 2139603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2140603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 2141603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public void onError(int errorCode, String errorMessage) { 2142a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana mNumErrors++; 2143a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana IAccountManagerResponse response = getResponseAndClose(); 2144a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (response != null) { 2145a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 214656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, getClass().getSimpleName() 214756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + " calling onError() on response " + response); 2148a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 2149a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana try { 2150a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana response.onError(errorCode, errorMessage); 2151a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } catch (RemoteException e) { 2152a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 2153a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana Log.v(TAG, "Session.onError: caught RemoteException while responding", e); 2154a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 2155a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 2156a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } else { 2157a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 2158a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana Log.v(TAG, "Session.onError: already closed"); 2159a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 2160603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2161603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2162b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana 2163b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana /** 2164b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana * find the component name for the authenticator and initiate a bind 2165b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana * if no authenticator or the bind fails then return false, otherwise return true 2166b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana */ 2167b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana private boolean bindToAuthenticator(String authenticatorType) { 21686ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey final AccountAuthenticatorCache.ServiceInfo<AuthenticatorDescription> authenticatorInfo; 21696ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey authenticatorInfo = mAuthenticatorCache.getServiceInfo( 21706ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey AuthenticatorDescription.newKey(authenticatorType), mAccounts.userId); 2171b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana if (authenticatorInfo == null) { 2172b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 2173b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana Log.v(TAG, "there is no authenticator for " + authenticatorType 2174b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana + ", bailing out"); 2175b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana } 2176b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana return false; 2177b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana } 2178b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana 2179b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana Intent intent = new Intent(); 2180b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana intent.setAction(AccountManager.ACTION_AUTHENTICATOR_INTENT); 2181b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana intent.setComponent(authenticatorInfo.componentName); 2182b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 2183b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana Log.v(TAG, "performing bindService to " + authenticatorInfo.componentName); 2184b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana } 218527b89e6658a0d233a53f5d7ca20dc57fec82d955Amith Yamasani if (!mContext.bindServiceAsUser(intent, this, Context.BIND_AUTO_CREATE, 218627b89e6658a0d233a53f5d7ca20dc57fec82d955Amith Yamasani new UserHandle(mAccounts.userId))) { 2187b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 2188b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana Log.v(TAG, "bindService to " + authenticatorInfo.componentName + " failed"); 2189b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana } 2190b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana return false; 2191b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana } 2192b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana 2193b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana 2194b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana return true; 2195b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana } 2196603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2197603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 2198603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private class MessageHandler extends Handler { 2199603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana MessageHandler(Looper looper) { 2200603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana super(looper); 2201603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 22023348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache 2203603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public void handleMessage(Message msg) { 2204603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana switch (msg.what) { 2205603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana case MESSAGE_TIMED_OUT: 2206603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana Session session = (Session)msg.obj; 2207603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana session.onTimedOut(); 2208603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana break; 2209603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 22105be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani case MESSAGE_COPY_SHARED_ACCOUNT: 22115be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani copyAccountToUser((Account) msg.obj, msg.arg1, msg.arg2); 22125be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani break; 22135be347bc527ca3eebb448f85245957c810e6b142Amith Yamasani 2214603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana default: 2215603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana throw new IllegalStateException("unhandled message: " + msg.what); 2216603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2217603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2218603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2219603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 222004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private static String getDatabaseName(int userId) { 222104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani File systemDir = Environment.getSystemSecureDirectory(); 222261f57379ca2c5b6290c8da7548fa17128f7ab24fAmith Yamasani File databaseFile = new File(Environment.getUserSystemDirectory(userId), DATABASE_NAME); 222304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani if (userId == 0) { 2224a23bb38628ac1f5dc4ebe6847faedc424dd5fce1Amith Yamasani // Migrate old file, if it exists, to the new location. 2225a23bb38628ac1f5dc4ebe6847faedc424dd5fce1Amith Yamasani // Make sure the new file doesn't already exist. A dummy file could have been 2226a23bb38628ac1f5dc4ebe6847faedc424dd5fce1Amith Yamasani // accidentally created in the old location, causing the new one to become corrupted 2227a23bb38628ac1f5dc4ebe6847faedc424dd5fce1Amith Yamasani // as well. 222804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani File oldFile = new File(systemDir, DATABASE_NAME); 2229a23bb38628ac1f5dc4ebe6847faedc424dd5fce1Amith Yamasani if (oldFile.exists() && !databaseFile.exists()) { 2230c6b0f99bb31405902b40a96f6491a9adcaaac169Marc Blank // Check for use directory; create if it doesn't exist, else renameTo will fail 223161f57379ca2c5b6290c8da7548fa17128f7ab24fAmith Yamasani File userDir = Environment.getUserSystemDirectory(userId); 2232c6b0f99bb31405902b40a96f6491a9adcaaac169Marc Blank if (!userDir.exists()) { 2233c6b0f99bb31405902b40a96f6491a9adcaaac169Marc Blank if (!userDir.mkdirs()) { 2234c6b0f99bb31405902b40a96f6491a9adcaaac169Marc Blank throw new IllegalStateException("User dir cannot be created: " + userDir); 2235c6b0f99bb31405902b40a96f6491a9adcaaac169Marc Blank } 2236c6b0f99bb31405902b40a96f6491a9adcaaac169Marc Blank } 2237c6b0f99bb31405902b40a96f6491a9adcaaac169Marc Blank if (!oldFile.renameTo(databaseFile)) { 2238c6b0f99bb31405902b40a96f6491a9adcaaac169Marc Blank throw new IllegalStateException("User dir cannot be migrated: " + databaseFile); 2239c6b0f99bb31405902b40a96f6491a9adcaaac169Marc Blank } 224004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 2241a8529f68671a8a118751cb6ad577f44eaf076b96Oscar Montemayor } 224204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani return databaseFile.getPath(); 2243a8529f68671a8a118751cb6ad577f44eaf076b96Oscar Montemayor } 2244a8529f68671a8a118751cb6ad577f44eaf076b96Oscar Montemayor 224504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani static class DatabaseHelper extends SQLiteOpenHelper { 2246a8529f68671a8a118751cb6ad577f44eaf076b96Oscar Montemayor 224704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani public DatabaseHelper(Context context, int userId) { 224804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani super(context, AccountManagerService.getDatabaseName(userId), null, DATABASE_VERSION); 2249603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2250603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 2251f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana /** 2252f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana * This call needs to be made while the mCacheLock is held. The way to 2253f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana * ensure this is to get the lock any time a method is called ont the DatabaseHelper 2254f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana * @param db The database. 2255f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana */ 2256603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana @Override 2257603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public void onCreate(SQLiteDatabase db) { 2258603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana db.execSQL("CREATE TABLE " + TABLE_ACCOUNTS + " ( " 2259603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + ACCOUNTS_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " 2260603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + ACCOUNTS_NAME + " TEXT NOT NULL, " 2261603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + ACCOUNTS_TYPE + " TEXT NOT NULL, " 2262603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + ACCOUNTS_PASSWORD + " TEXT, " 2263603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + "UNIQUE(" + ACCOUNTS_NAME + "," + ACCOUNTS_TYPE + "))"); 2264603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 2265603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana db.execSQL("CREATE TABLE " + TABLE_AUTHTOKENS + " ( " 2266603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + AUTHTOKENS_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " 2267603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + AUTHTOKENS_ACCOUNTS_ID + " INTEGER NOT NULL, " 2268603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + AUTHTOKENS_TYPE + " TEXT NOT NULL, " 2269603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + AUTHTOKENS_AUTHTOKEN + " TEXT, " 2270603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + "UNIQUE (" + AUTHTOKENS_ACCOUNTS_ID + "," + AUTHTOKENS_TYPE + "))"); 2271603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 2272d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana createGrantsTable(db); 2273d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 2274603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana db.execSQL("CREATE TABLE " + TABLE_EXTRAS + " ( " 2275603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + EXTRAS_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " 2276603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + EXTRAS_ACCOUNTS_ID + " INTEGER, " 2277603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + EXTRAS_KEY + " TEXT NOT NULL, " 2278603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + EXTRAS_VALUE + " TEXT, " 2279603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + "UNIQUE(" + EXTRAS_ACCOUNTS_ID + "," + EXTRAS_KEY + "))"); 2280603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 2281603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana db.execSQL("CREATE TABLE " + TABLE_META + " ( " 2282603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + META_KEY + " TEXT PRIMARY KEY NOT NULL, " 2283603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + META_VALUE + " TEXT)"); 2284a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 228567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani createSharedAccountsTable(db); 228667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani 2287d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana createAccountsDeletionTrigger(db); 2288d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2289d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 229067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani private void createSharedAccountsTable(SQLiteDatabase db) { 229167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani db.execSQL("CREATE TABLE " + TABLE_SHARED_ACCOUNTS + " ( " 229267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani + ACCOUNTS_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " 229367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani + ACCOUNTS_NAME + " TEXT NOT NULL, " 229467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani + ACCOUNTS_TYPE + " TEXT NOT NULL, " 229567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani + "UNIQUE(" + ACCOUNTS_NAME + "," + ACCOUNTS_TYPE + "))"); 229667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 229767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani 2298d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private void createAccountsDeletionTrigger(SQLiteDatabase db) { 2299a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana db.execSQL("" 2300a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + " CREATE TRIGGER " + TABLE_ACCOUNTS + "Delete DELETE ON " + TABLE_ACCOUNTS 2301a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + " BEGIN" 2302a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + " DELETE FROM " + TABLE_AUTHTOKENS 2303a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + " WHERE " + AUTHTOKENS_ACCOUNTS_ID + "=OLD." + ACCOUNTS_ID + " ;" 2304a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + " DELETE FROM " + TABLE_EXTRAS 2305a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + " WHERE " + EXTRAS_ACCOUNTS_ID + "=OLD." + ACCOUNTS_ID + " ;" 2306d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + " DELETE FROM " + TABLE_GRANTS 2307d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + " WHERE " + GRANTS_ACCOUNTS_ID + "=OLD." + ACCOUNTS_ID + " ;" 2308a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + " END"); 2309603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2310603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 2311d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private void createGrantsTable(SQLiteDatabase db) { 2312d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana db.execSQL("CREATE TABLE " + TABLE_GRANTS + " ( " 2313d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + GRANTS_ACCOUNTS_ID + " INTEGER NOT NULL, " 2314d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + GRANTS_AUTH_TOKEN_TYPE + " STRING NOT NULL, " 2315d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + GRANTS_GRANTEE_UID + " INTEGER NOT NULL, " 2316d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + "UNIQUE (" + GRANTS_ACCOUNTS_ID + "," + GRANTS_AUTH_TOKEN_TYPE 2317d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + "," + GRANTS_GRANTEE_UID + "))"); 2318d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2319d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 2320603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana @Override 2321603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 2322a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana Log.e(TAG, "upgrade from version " + oldVersion + " to version " + newVersion); 2323603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 2324a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (oldVersion == 1) { 2325d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana // no longer need to do anything since the work is done 2326d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana // when upgrading from version 2 2327d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana oldVersion++; 2328d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2329d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 2330d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (oldVersion == 2) { 2331d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana createGrantsTable(db); 2332d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana db.execSQL("DROP TRIGGER " + TABLE_ACCOUNTS + "Delete"); 2333d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana createAccountsDeletionTrigger(db); 2334a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana oldVersion++; 2335a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 23363348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache 23373348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache if (oldVersion == 3) { 23383348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache db.execSQL("UPDATE " + TABLE_ACCOUNTS + " SET " + ACCOUNTS_TYPE + 23393348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache " = 'com.google' WHERE " + ACCOUNTS_TYPE + " == 'com.google.GAIA'"); 23403348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache oldVersion++; 23413348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache } 234267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani 234367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani if (oldVersion == 4) { 234467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani createSharedAccountsTable(db); 234567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani oldVersion++; 234667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 234767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani 234867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani if (oldVersion != newVersion) { 234967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani Log.e(TAG, "failed to upgrade version " + oldVersion + " to version " + newVersion); 235067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 2351603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2352603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 2353603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana @Override 2354603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public void onOpen(SQLiteDatabase db) { 2355603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "opened database " + DATABASE_NAME); 2356603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2357603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2358603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 2359603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public IBinder onBind(Intent intent) { 2360603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana return asBinder(); 2361603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2362a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 23631cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks /** 23641cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks * Searches array of arguments for the specified string 23651cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks * @param args array of argument strings 23661cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks * @param value value to search for 23671cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks * @return true if the value is contained in the array 23681cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks */ 23691cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks private static boolean scanArgs(String[] args, String value) { 23701cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks if (args != null) { 23711cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks for (String arg : args) { 23721cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks if (value.equals(arg)) { 23731cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks return true; 23741cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks } 2375a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 2376a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 23771cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks return false; 23781cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks } 2379a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 23806eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey @Override 23811cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) { 23823abd75ba3a981850cac43a401d0014a836559cb0Kenny Root if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 23833abd75ba3a981850cac43a401d0014a836559cb0Kenny Root != PackageManager.PERMISSION_GRANTED) { 23843abd75ba3a981850cac43a401d0014a836559cb0Kenny Root fout.println("Permission Denial: can't dump AccountsManager from from pid=" 23853abd75ba3a981850cac43a401d0014a836559cb0Kenny Root + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 23863abd75ba3a981850cac43a401d0014a836559cb0Kenny Root + " without permission " + android.Manifest.permission.DUMP); 23873abd75ba3a981850cac43a401d0014a836559cb0Kenny Root return; 23883abd75ba3a981850cac43a401d0014a836559cb0Kenny Root } 238904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final boolean isCheckinRequest = scanArgs(args, "--checkin") || scanArgs(args, "-c"); 23906eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey final IndentingPrintWriter ipw = new IndentingPrintWriter(fout, " "); 23916eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey 23926eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey final List<UserInfo> users = getUserManager().getUsers(); 23936eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey for (UserInfo user : users) { 23946eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey ipw.println("User " + user + ":"); 23956eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey ipw.increaseIndent(); 23966eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey dumpUser(getUserAccounts(user.id), fd, ipw, args, isCheckinRequest); 23976eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey ipw.println(); 23986eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey ipw.decreaseIndent(); 239904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 240004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 24011cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks 240204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private void dumpUser(UserAccounts userAccounts, FileDescriptor fd, PrintWriter fout, 240304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani String[] args, boolean isCheckinRequest) { 240404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (userAccounts.cacheLock) { 240504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = userAccounts.openHelper.getReadableDatabase(); 2406a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 2407f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (isCheckinRequest) { 2408f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana // This is a checkin request. *Only* upload the account types and the count of each. 2409f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana Cursor cursor = db.query(TABLE_ACCOUNTS, ACCOUNT_TYPE_COUNT_PROJECTION, 2410f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana null, null, ACCOUNTS_TYPE, null, null); 2411f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana try { 2412f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana while (cursor.moveToNext()) { 2413f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana // print type,count 2414f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana fout.println(cursor.getString(0) + "," + cursor.getString(1)); 2415f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 2416f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } finally { 2417f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (cursor != null) { 2418f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana cursor.close(); 2419f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 24201cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks } 2421f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } else { 2422df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani Account[] accounts = getAccountsFromCacheLocked(userAccounts, null /* type */, 242327db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani Process.myUid(), null); 2424f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana fout.println("Accounts: " + accounts.length); 2425f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana for (Account account : accounts) { 2426f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana fout.println(" " + account); 24271cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks } 2428307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana 2429f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana fout.println(); 2430f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana synchronized (mSessions) { 2431f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana final long now = SystemClock.elapsedRealtime(); 2432f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana fout.println("Active Sessions: " + mSessions.size()); 2433f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana for (Session session : mSessions.values()) { 2434f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana fout.println(" " + session.toDebugString(now)); 2435f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 24361cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks } 24371cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks 2438f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana fout.println(); 24396ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey mAuthenticatorCache.dump(fd, fout, args, userAccounts.userId); 2440f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 24411cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks } 2442a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 2443a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 244404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private void doNotification(UserAccounts accounts, Account account, CharSequence message, 24454120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn Intent intent, int userId) { 244626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 244726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 244826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 244926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana Log.v(TAG, "doNotification: " + message + " intent:" + intent); 245026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 2451a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 2452d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (intent.getComponent() != null && 2453d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana GrantCredentialsPermissionActivity.class.getName().equals( 2454d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana intent.getComponent().getClassName())) { 24554120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn createNoCredentialsPermissionNotification(account, intent, userId); 2456d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } else { 245704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final Integer notificationId = getSigninRequiredNotificationId(accounts, account); 245833f889ae270f888f8fdc084f5f1f3d443532a46aFred Quintana intent.addCategory(String.valueOf(notificationId)); 2459d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Notification n = new Notification(android.R.drawable.stat_sys_warning, null, 2460d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 0 /* when */); 246150cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn UserHandle user = new UserHandle(userId); 246233f889ae270f888f8fdc084f5f1f3d443532a46aFred Quintana final String notificationTitleFormat = 246333f889ae270f888f8fdc084f5f1f3d443532a46aFred Quintana mContext.getText(R.string.notification_title).toString(); 246433f889ae270f888f8fdc084f5f1f3d443532a46aFred Quintana n.setLatestEventInfo(mContext, 246533f889ae270f888f8fdc084f5f1f3d443532a46aFred Quintana String.format(notificationTitleFormat, account.name), 24664120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn message, PendingIntent.getActivityAsUser( 24674120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn mContext, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT, 246850cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn null, user)); 246950cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn installNotification(notificationId, n, user); 2470d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 247126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 247226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 247326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 2474a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 2475a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 247650cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn protected void installNotification(final int notificationId, final Notification n, 247750cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn UserHandle user) { 247856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana ((NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE)) 247950cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn .notifyAsUser(null, notificationId, n, user); 248056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 248156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 248250cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn protected void cancelNotification(int id, UserHandle user) { 248326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 248426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 248526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana ((NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE)) 248650cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn .cancelAsUser(null, id, user); 248726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 248826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 248926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 2490a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 2491d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 2492b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana /** Succeeds if any of the specified permissions are granted. */ 2493b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana private void checkBinderPermission(String... permissions) { 2494d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana final int uid = Binder.getCallingUid(); 2495b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana 2496b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana for (String perm : permissions) { 2497b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana if (mContext.checkCallingOrSelfPermission(perm) == PackageManager.PERMISSION_GRANTED) { 2498b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 249956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, " caller uid " + uid + " has " + perm); 2500b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana } 2501b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana return; 2502b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana } 2503d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2504b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana 2505b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana String msg = "caller uid " + uid + " lacks any of " + TextUtils.join(",", permissions); 250656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.w(TAG, " " + msg); 2507b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana throw new SecurityException(msg); 2508d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2509d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 251067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani private int handleIncomingUser(int userId) { 251167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani try { 251267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani return ActivityManagerNative.getDefault().handleIncomingUser( 251367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani Binder.getCallingPid(), Binder.getCallingUid(), userId, true, true, "", null); 251467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } catch (RemoteException re) { 251567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani // Shouldn't happen, local. 251667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 251767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani return userId; 251867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 251967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani 25206ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey private boolean inSystemImage(int callingUid) { 25216ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey final int callingUserId = UserHandle.getUserId(callingUid); 25226ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey 25236ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey final PackageManager userPackageManager; 25246ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey try { 25256ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey userPackageManager = mContext.createPackageContextAsUser( 25266ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey "android", 0, new UserHandle(callingUserId)).getPackageManager(); 25276ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey } catch (NameNotFoundException e) { 25286ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey return false; 25296ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey } 25306ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey 25316ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey String[] packages = userPackageManager.getPackagesForUid(callingUid); 25327be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana for (String name : packages) { 25337be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana try { 25346ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey PackageInfo packageInfo = userPackageManager.getPackageInfo(name, 0 /* flags */); 253556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (packageInfo != null 253656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana && (packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 25377be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana return true; 25387be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana } 25397be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana } catch (PackageManager.NameNotFoundException e) { 25407be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana return false; 25417be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana } 25427be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana } 25437be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana return false; 25447be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana } 25457be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana 2546d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private boolean permissionIsGranted(Account account, String authTokenType, int callerUid) { 2547b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana final boolean inSystemImage = inSystemImage(callerUid); 254831957f1badbb900bbfe211317e1ea992d650a72dFred Quintana final boolean fromAuthenticator = account != null 254931957f1badbb900bbfe211317e1ea992d650a72dFred Quintana && hasAuthenticatorUid(account.type, callerUid); 255031957f1badbb900bbfe211317e1ea992d650a72dFred Quintana final boolean hasExplicitGrants = account != null 255104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani && hasExplicitlyGrantedPermission(account, authTokenType, callerUid); 2552d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 2553d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Log.v(TAG, "checkGrantsOrCallingUidAgainstAuthenticator: caller uid " 255456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + callerUid + ", " + account 2555d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + ": is authenticator? " + fromAuthenticator 2556d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + ", has explicit permission? " + hasExplicitGrants); 2557d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2558b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana return fromAuthenticator || hasExplicitGrants || inSystemImage; 2559d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2560d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 25611a23191bbde11505d6e0c25c04a60b41cb27fd31Fred Quintana private boolean hasAuthenticatorUid(String accountType, int callingUid) { 25626ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey final int callingUserId = UserHandle.getUserId(callingUid); 2563d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana for (RegisteredServicesCache.ServiceInfo<AuthenticatorDescription> serviceInfo : 25646ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey mAuthenticatorCache.getAllServices(callingUserId)) { 2565d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (serviceInfo.type.type.equals(accountType)) { 2566ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana return (serviceInfo.uid == callingUid) || 256756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana (mPackageManager.checkSignatures(serviceInfo.uid, callingUid) 2568ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana == PackageManager.SIGNATURE_MATCH); 2569d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2570d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2571d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana return false; 2572d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2573d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 257404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private boolean hasExplicitlyGrantedPermission(Account account, String authTokenType, 257504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani int callerUid) { 257627db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani if (callerUid == Process.SYSTEM_UID) { 2577d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana return true; 2578d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 257904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 258004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 258104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getReadableDatabase(); 258204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani String[] args = { String.valueOf(callerUid), authTokenType, 2583f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana account.name, account.type}; 2584f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana final boolean permissionGranted = 2585f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana DatabaseUtils.longForQuery(db, COUNT_OF_MATCHING_GRANTS, args) != 0; 2586f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (!permissionGranted && ActivityManager.isRunningInTestHarness()) { 2587f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana // TODO: Skip this check when running automated tests. Replace this 2588f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana // with a more general solution. 2589f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana Log.d(TAG, "no credentials permission for usage of " + account + ", " 259004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani + authTokenType + " by uid " + callerUid 2591f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana + " but ignoring since device is in test harness."); 2592f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return true; 2593f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 2594f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return permissionGranted; 2595d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2596d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2597d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 2598d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private void checkCallingUidAgainstAuthenticator(Account account) { 2599d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana final int uid = Binder.getCallingUid(); 260031957f1badbb900bbfe211317e1ea992d650a72dFred Quintana if (account == null || !hasAuthenticatorUid(account.type, uid)) { 2601d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana String msg = "caller uid " + uid + " is different than the authenticator's uid"; 2602d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Log.w(TAG, msg); 2603d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana throw new SecurityException(msg); 2604d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2605d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 2606d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Log.v(TAG, "caller uid " + uid + " is the same as the authenticator's uid"); 2607d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2608d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2609d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 2610d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private void checkAuthenticateAccountsPermission(Account account) { 2611d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkBinderPermission(Manifest.permission.AUTHENTICATE_ACCOUNTS); 2612d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkCallingUidAgainstAuthenticator(account); 2613d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2614d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 2615d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private void checkReadAccountsPermission() { 2616d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkBinderPermission(Manifest.permission.GET_ACCOUNTS); 2617d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2618d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 2619d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private void checkManageAccountsPermission() { 2620d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkBinderPermission(Manifest.permission.MANAGE_ACCOUNTS); 2621d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2622d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 2623b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana private void checkManageAccountsOrUseCredentialsPermissions() { 2624b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana checkBinderPermission(Manifest.permission.MANAGE_ACCOUNTS, 2625b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana Manifest.permission.USE_CREDENTIALS); 2626b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana } 2627b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana 2628e4cf73437a18c1444055f88a1fcc0d146ec23ac5Amith Yamasani private boolean canUserModifyAccounts(int callingUid) { 262927db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani if (callingUid != Process.myUid()) { 263027db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani if (getUserManager().getUserRestrictions( 263127db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani new UserHandle(UserHandle.getUserId(callingUid))) 263227db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani .getBoolean(UserManager.DISALLOW_MODIFY_ACCOUNTS)) { 2633e4cf73437a18c1444055f88a1fcc0d146ec23ac5Amith Yamasani return false; 2634e4cf73437a18c1444055f88a1fcc0d146ec23ac5Amith Yamasani } 2635e4cf73437a18c1444055f88a1fcc0d146ec23ac5Amith Yamasani } 2636e4cf73437a18c1444055f88a1fcc0d146ec23ac5Amith Yamasani return true; 2637e4cf73437a18c1444055f88a1fcc0d146ec23ac5Amith Yamasani } 2638e4cf73437a18c1444055f88a1fcc0d146ec23ac5Amith Yamasani 2639d9640ec712806508877868d08aafaa2d715ff441Fred Quintana public void updateAppPermission(Account account, String authTokenType, int uid, boolean value) 2640d9640ec712806508877868d08aafaa2d715ff441Fred Quintana throws RemoteException { 2641d9640ec712806508877868d08aafaa2d715ff441Fred Quintana final int callingUid = getCallingUid(); 2642d9640ec712806508877868d08aafaa2d715ff441Fred Quintana 264327db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani if (callingUid != Process.SYSTEM_UID) { 2644d9640ec712806508877868d08aafaa2d715ff441Fred Quintana throw new SecurityException(); 2645d9640ec712806508877868d08aafaa2d715ff441Fred Quintana } 2646d9640ec712806508877868d08aafaa2d715ff441Fred Quintana 2647d9640ec712806508877868d08aafaa2d715ff441Fred Quintana if (value) { 2648d9640ec712806508877868d08aafaa2d715ff441Fred Quintana grantAppPermission(account, authTokenType, uid); 2649d9640ec712806508877868d08aafaa2d715ff441Fred Quintana } else { 2650d9640ec712806508877868d08aafaa2d715ff441Fred Quintana revokeAppPermission(account, authTokenType, uid); 2651d9640ec712806508877868d08aafaa2d715ff441Fred Quintana } 2652d9640ec712806508877868d08aafaa2d715ff441Fred Quintana } 2653d9640ec712806508877868d08aafaa2d715ff441Fred Quintana 2654d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana /** 2655d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * Allow callers with the given uid permission to get credentials for account/authTokenType. 2656d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * <p> 2657d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * Although this is public it can only be accessed via the AccountManagerService object 2658d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * which is in the system. This means we don't need to protect it with permissions. 2659d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * @hide 2660d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana */ 2661d9640ec712806508877868d08aafaa2d715ff441Fred Quintana private void grantAppPermission(Account account, String authTokenType, int uid) { 2662382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null || authTokenType == null) { 2663382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana Log.e(TAG, "grantAppPermission: called with invalid arguments", new Exception()); 266431957f1badbb900bbfe211317e1ea992d650a72dFred Quintana return; 266531957f1badbb900bbfe211317e1ea992d650a72dFred Quintana } 2666f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackborn UserAccounts accounts = getUserAccounts(UserHandle.getUserId(uid)); 266704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 266804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getWritableDatabase(); 2669f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.beginTransaction(); 2670f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana try { 2671f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana long accountId = getAccountIdLocked(db, account); 2672f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (accountId >= 0) { 2673f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana ContentValues values = new ContentValues(); 2674f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana values.put(GRANTS_ACCOUNTS_ID, accountId); 2675f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana values.put(GRANTS_AUTH_TOKEN_TYPE, authTokenType); 2676f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana values.put(GRANTS_GRANTEE_UID, uid); 2677f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.insert(TABLE_GRANTS, GRANTS_ACCOUNTS_ID, values); 2678f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.setTransactionSuccessful(); 2679f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 2680f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } finally { 2681f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.endTransaction(); 2682d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 268350cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn cancelNotification(getCredentialPermissionNotificationId(account, authTokenType, uid), 268450cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn new UserHandle(accounts.userId)); 2685d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2686d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2687d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 2688d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana /** 2689d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * Don't allow callers with the given uid permission to get credentials for 2690d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * account/authTokenType. 2691d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * <p> 2692d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * Although this is public it can only be accessed via the AccountManagerService object 2693d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * which is in the system. This means we don't need to protect it with permissions. 2694d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * @hide 2695d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana */ 2696d9640ec712806508877868d08aafaa2d715ff441Fred Quintana private void revokeAppPermission(Account account, String authTokenType, int uid) { 2697382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null || authTokenType == null) { 2698382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana Log.e(TAG, "revokeAppPermission: called with invalid arguments", new Exception()); 269931957f1badbb900bbfe211317e1ea992d650a72dFred Quintana return; 270031957f1badbb900bbfe211317e1ea992d650a72dFred Quintana } 2701f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackborn UserAccounts accounts = getUserAccounts(UserHandle.getUserId(uid)); 270204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 270304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getWritableDatabase(); 2704f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.beginTransaction(); 2705f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana try { 2706f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana long accountId = getAccountIdLocked(db, account); 2707f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (accountId >= 0) { 2708f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.delete(TABLE_GRANTS, 2709f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana GRANTS_ACCOUNTS_ID + "=? AND " + GRANTS_AUTH_TOKEN_TYPE + "=? AND " 2710f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana + GRANTS_GRANTEE_UID + "=?", 2711f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana new String[]{String.valueOf(accountId), authTokenType, 2712f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana String.valueOf(uid)}); 2713f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.setTransactionSuccessful(); 2714f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 2715f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } finally { 2716f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.endTransaction(); 2717d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 271850cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn cancelNotification(getCredentialPermissionNotificationId(account, authTokenType, uid), 271950cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn new UserHandle(accounts.userId)); 2720d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2721d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 272256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 272356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana static final private String stringArrayToString(String[] value) { 272456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana return value != null ? ("[" + TextUtils.join(",", value) + "]") : null; 272556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 272656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 272704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private void removeAccountFromCacheLocked(UserAccounts accounts, Account account) { 272804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final Account[] oldAccountsForType = accounts.accountCache.get(account.type); 2729f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (oldAccountsForType != null) { 2730f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana ArrayList<Account> newAccountsList = new ArrayList<Account>(); 2731f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana for (Account curAccount : oldAccountsForType) { 2732f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (!curAccount.equals(account)) { 2733f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana newAccountsList.add(curAccount); 273456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 273556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 2736f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (newAccountsList.isEmpty()) { 273704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.accountCache.remove(account.type); 2738f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } else { 2739f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana Account[] newAccountsForType = new Account[newAccountsList.size()]; 2740f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana newAccountsForType = newAccountsList.toArray(newAccountsForType); 274104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.accountCache.put(account.type, newAccountsForType); 2742f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 274356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 274404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.userDataCache.remove(account); 274504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.authTokenCache.remove(account); 274656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 274756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 274856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana /** 274956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana * This assumes that the caller has already checked that the account is not already present. 275056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana */ 275104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private void insertAccountIntoCacheLocked(UserAccounts accounts, Account account) { 275204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani Account[] accountsForType = accounts.accountCache.get(account.type); 2753f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana int oldLength = (accountsForType != null) ? accountsForType.length : 0; 2754f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana Account[] newAccountsForType = new Account[oldLength + 1]; 2755f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (accountsForType != null) { 2756f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana System.arraycopy(accountsForType, 0, newAccountsForType, 0, oldLength); 2757f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 2758f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana newAccountsForType[oldLength] = account; 275904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.accountCache.put(account.type, newAccountsForType); 2760f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 2761f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana 2762df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani private Account[] filterSharedAccounts(UserAccounts userAccounts, Account[] unfiltered, 276327db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani int callingUid, String callingPackage) { 2764df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani if (getUserManager() == null || userAccounts == null || userAccounts.userId < 0 276527db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani || callingUid == Process.myUid()) { 2766df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani return unfiltered; 2767df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani } 2768df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani if (mUserManager.getUserInfo(userAccounts.userId).isRestricted()) { 2769df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani String[] packages = mPackageManager.getPackagesForUid(callingUid); 27700ac1fc9d233b8671f371a71e2a6374b47ef069a9Amith Yamasani // If any of the packages is a white listed package, return the full set, 2771df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani // otherwise return non-shared accounts only. 2772df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani // This might be a temporary way to specify a whitelist 2773df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani String whiteList = mContext.getResources().getString( 2774df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani com.android.internal.R.string.config_appsAuthorizedForSharedAccounts); 2775df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani for (String packageName : packages) { 2776df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani if (whiteList.contains(";" + packageName + ";")) { 2777df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani return unfiltered; 2778df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani } 2779df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani } 2780df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani ArrayList<Account> allowed = new ArrayList<Account>(); 2781df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani Account[] sharedAccounts = getSharedAccountsAsUser(userAccounts.userId); 2782df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani if (sharedAccounts == null || sharedAccounts.length == 0) return unfiltered; 27830ac1fc9d233b8671f371a71e2a6374b47ef069a9Amith Yamasani String requiredAccountType = ""; 27840ac1fc9d233b8671f371a71e2a6374b47ef069a9Amith Yamasani try { 27850ac1fc9d233b8671f371a71e2a6374b47ef069a9Amith Yamasani for (String packageName : packages) { 27860ac1fc9d233b8671f371a71e2a6374b47ef069a9Amith Yamasani PackageInfo pi = mPackageManager.getPackageInfo(packageName, 0); 27870ac1fc9d233b8671f371a71e2a6374b47ef069a9Amith Yamasani if (pi != null && pi.restrictedAccountType != null) { 27880ac1fc9d233b8671f371a71e2a6374b47ef069a9Amith Yamasani requiredAccountType = pi.restrictedAccountType; 278927db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani // If it matches the package name of the original caller, use this choice. 279027db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani if (callingPackage != null && packageName.equals(callingPackage)) { 279127db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani break; 279227db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani } 2793df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani } 2794df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani } 27950ac1fc9d233b8671f371a71e2a6374b47ef069a9Amith Yamasani } catch (NameNotFoundException nnfe) { 27960ac1fc9d233b8671f371a71e2a6374b47ef069a9Amith Yamasani } 27970ac1fc9d233b8671f371a71e2a6374b47ef069a9Amith Yamasani for (Account account : unfiltered) { 27980ac1fc9d233b8671f371a71e2a6374b47ef069a9Amith Yamasani if (account.type.equals(requiredAccountType)) { 2799df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani allowed.add(account); 28000ac1fc9d233b8671f371a71e2a6374b47ef069a9Amith Yamasani } else { 28010ac1fc9d233b8671f371a71e2a6374b47ef069a9Amith Yamasani boolean found = false; 28020ac1fc9d233b8671f371a71e2a6374b47ef069a9Amith Yamasani for (Account shared : sharedAccounts) { 28030ac1fc9d233b8671f371a71e2a6374b47ef069a9Amith Yamasani if (shared.equals(account)) { 28040ac1fc9d233b8671f371a71e2a6374b47ef069a9Amith Yamasani found = true; 28050ac1fc9d233b8671f371a71e2a6374b47ef069a9Amith Yamasani break; 28060ac1fc9d233b8671f371a71e2a6374b47ef069a9Amith Yamasani } 28070ac1fc9d233b8671f371a71e2a6374b47ef069a9Amith Yamasani } 28080ac1fc9d233b8671f371a71e2a6374b47ef069a9Amith Yamasani if (!found) { 28090ac1fc9d233b8671f371a71e2a6374b47ef069a9Amith Yamasani allowed.add(account); 28100ac1fc9d233b8671f371a71e2a6374b47ef069a9Amith Yamasani } 2811df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani } 2812df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani } 2813df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani Account[] filtered = new Account[allowed.size()]; 2814df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani allowed.toArray(filtered); 2815df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani return filtered; 2816df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani } else { 2817df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani return unfiltered; 2818df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani } 2819df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani } 2820df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani 282127db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani /* 282227db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani * packageName can be null. If not null, it should be used to filter out restricted accounts 282327db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani * that the package is not allowed to access. 282427db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani */ 2825df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani protected Account[] getAccountsFromCacheLocked(UserAccounts userAccounts, String accountType, 282627db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani int callingUid, String callingPackage) { 2827f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (accountType != null) { 282804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final Account[] accounts = userAccounts.accountCache.get(accountType); 2829f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (accounts == null) { 2830f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return EMPTY_ACCOUNT_ARRAY; 283156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } else { 2832df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani return filterSharedAccounts(userAccounts, Arrays.copyOf(accounts, accounts.length), 283327db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani callingUid, callingPackage); 2834f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 2835f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } else { 2836f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana int totalLength = 0; 283704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani for (Account[] accounts : userAccounts.accountCache.values()) { 2838f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana totalLength += accounts.length; 2839f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 2840f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (totalLength == 0) { 2841f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return EMPTY_ACCOUNT_ARRAY; 2842f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 2843f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana Account[] accounts = new Account[totalLength]; 2844f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana totalLength = 0; 284504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani for (Account[] accountsOfType : userAccounts.accountCache.values()) { 2846f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana System.arraycopy(accountsOfType, 0, accounts, totalLength, 2847f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana accountsOfType.length); 2848f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana totalLength += accountsOfType.length; 284956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 285027db46850b708070452c0ce49daf5f79503fbde6Amith Yamasani return filterSharedAccounts(userAccounts, accounts, callingUid, callingPackage); 285156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 285256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 285356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 285404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani protected void writeUserDataIntoCacheLocked(UserAccounts accounts, final SQLiteDatabase db, 285504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani Account account, String key, String value) { 285604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani HashMap<String, String> userDataForAccount = accounts.userDataCache.get(account); 2857f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (userDataForAccount == null) { 2858f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana userDataForAccount = readUserDataForAccountFromDatabaseLocked(db, account); 285904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.userDataCache.put(account, userDataForAccount); 2860f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 2861f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (value == null) { 2862f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana userDataForAccount.remove(key); 2863f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } else { 2864f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana userDataForAccount.put(key, value); 286556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 286656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 286756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 286804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani protected void writeAuthTokenIntoCacheLocked(UserAccounts accounts, final SQLiteDatabase db, 286904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani Account account, String key, String value) { 287004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani HashMap<String, String> authTokensForAccount = accounts.authTokenCache.get(account); 2871f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (authTokensForAccount == null) { 2872f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana authTokensForAccount = readAuthTokensForAccountFromDatabaseLocked(db, account); 287304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.authTokenCache.put(account, authTokensForAccount); 2874f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 2875f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (value == null) { 2876f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana authTokensForAccount.remove(key); 2877f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } else { 2878f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana authTokensForAccount.put(key, value); 287956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 288056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 288156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 288204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani protected String readAuthTokenInternal(UserAccounts accounts, Account account, 288304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani String authTokenType) { 288404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 288504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani HashMap<String, String> authTokensForAccount = accounts.authTokenCache.get(account); 288656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (authTokensForAccount == null) { 288756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana // need to populate the cache for this account 288804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getReadableDatabase(); 2889f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana authTokensForAccount = readAuthTokensForAccountFromDatabaseLocked(db, account); 289004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.authTokenCache.put(account, authTokensForAccount); 289156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 289256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana return authTokensForAccount.get(authTokenType); 289356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 289456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 289556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 289604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani protected String readUserDataInternal(UserAccounts accounts, Account account, String key) { 289704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 289804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani HashMap<String, String> userDataForAccount = accounts.userDataCache.get(account); 289956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (userDataForAccount == null) { 290056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana // need to populate the cache for this account 290104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getReadableDatabase(); 2902f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana userDataForAccount = readUserDataForAccountFromDatabaseLocked(db, account); 290304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.userDataCache.put(account, userDataForAccount); 290456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 290556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana return userDataForAccount.get(key); 290656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 290756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 290856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 2909f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana protected HashMap<String, String> readUserDataForAccountFromDatabaseLocked( 2910f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana final SQLiteDatabase db, Account account) { 291156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana HashMap<String, String> userDataForAccount = new HashMap<String, String>(); 291256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Cursor cursor = db.query(TABLE_EXTRAS, 291356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana COLUMNS_EXTRAS_KEY_AND_VALUE, 291456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana SELECTION_USERDATA_BY_ACCOUNT, 291556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana new String[]{account.name, account.type}, 291656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana null, null, null); 291756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana try { 291856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana while (cursor.moveToNext()) { 291956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final String tmpkey = cursor.getString(0); 292056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final String value = cursor.getString(1); 292156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana userDataForAccount.put(tmpkey, value); 292256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 292356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } finally { 292456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana cursor.close(); 292556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 292656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana return userDataForAccount; 292756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 292856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 2929f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana protected HashMap<String, String> readAuthTokensForAccountFromDatabaseLocked( 2930f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana final SQLiteDatabase db, Account account) { 293156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana HashMap<String, String> authTokensForAccount = new HashMap<String, String>(); 293256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Cursor cursor = db.query(TABLE_AUTHTOKENS, 293356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana COLUMNS_AUTHTOKENS_TYPE_AND_AUTHTOKEN, 293456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana SELECTION_AUTHTOKENS_BY_ACCOUNT, 293556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana new String[]{account.name, account.type}, 293656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana null, null, null); 293756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana try { 293856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana while (cursor.moveToNext()) { 293956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final String type = cursor.getString(0); 294056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final String authToken = cursor.getString(1); 294156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana authTokensForAccount.put(type, authToken); 294256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 294356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } finally { 294456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana cursor.close(); 294556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 294656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana return authTokensForAccount; 294756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 2948603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana} 2949