AccountManagerService.java revision 3df7d697ca86ee2081bcfba31bcbd3ae4f4bcdf8
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; 257a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkeyimport android.accounts.GrantCredentialsPermissionActivity; 267a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkeyimport android.accounts.IAccountAuthenticator; 277a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkeyimport android.accounts.IAccountAuthenticatorResponse; 287a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkeyimport android.accounts.IAccountManager; 297a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkeyimport android.accounts.IAccountManagerResponse; 303b4fcbc9f13bab6a2e9e5c37cc5e18fec7341c04Brett Chabotimport android.app.ActivityManager; 316ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkeyimport android.app.ActivityManagerNative; 32885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongkerimport android.app.Notification; 33885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongkerimport android.app.NotificationManager; 34885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongkerimport android.app.PendingIntent; 35a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.content.BroadcastReceiver; 36885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongkerimport android.content.ComponentName; 37a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.content.ContentValues; 38a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.content.Context; 39a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.content.Intent; 40a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.content.IntentFilter; 41b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintanaimport android.content.ServiceConnection; 42885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongkerimport android.content.pm.ApplicationInfo; 43885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongkerimport android.content.pm.PackageInfo; 44d4a1d2e14297a3387fdb5761090961e714370492Fred Quintanaimport android.content.pm.PackageManager; 456ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkeyimport android.content.pm.PackageManager.NameNotFoundException; 46d4a1d2e14297a3387fdb5761090961e714370492Fred Quintanaimport android.content.pm.RegisteredServicesCache; 473ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintanaimport android.content.pm.RegisteredServicesCacheListener; 486eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkeyimport android.content.pm.UserInfo; 49603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintanaimport android.database.Cursor; 50603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintanaimport android.database.DatabaseUtils; 51a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.database.sqlite.SQLiteDatabase; 52a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.database.sqlite.SQLiteOpenHelper; 53885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongkerimport android.os.Binder; 54a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.os.Bundle; 55a8529f68671a8a118751cb6ad577f44eaf076b96Oscar Montemayorimport android.os.Environment; 56a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.os.Handler; 57a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.os.HandlerThread; 58a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.os.IBinder; 59a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.os.Looper; 60a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.os.Message; 61a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.os.RemoteException; 62a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.os.SystemClock; 63f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackbornimport android.os.UserHandle; 64258848d2ae04f447ff1c18023fa76b139fcc0862Amith Yamasaniimport android.os.UserManager; 65a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.text.TextUtils; 66a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.util.Log; 67d4a1d2e14297a3387fdb5761090961e714370492Fred Quintanaimport android.util.Pair; 686eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkeyimport android.util.Slog; 6904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasaniimport android.util.SparseArray; 70603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 71b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolacheimport com.android.internal.R; 7267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasaniimport com.android.internal.util.ArrayUtils; 7304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasaniimport com.android.internal.util.IndentingPrintWriter; 746ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkeyimport com.google.android.collect.Lists; 756ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkeyimport com.google.android.collect.Sets; 76b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache 77a8529f68671a8a118751cb6ad577f44eaf076b96Oscar Montemayorimport java.io.File; 78a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport java.io.FileDescriptor; 79a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport java.io.PrintWriter; 80a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport java.util.ArrayList; 8156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintanaimport java.util.Arrays; 82a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport java.util.Collection; 83d4a1d2e14297a3387fdb5761090961e714370492Fred Quintanaimport java.util.HashMap; 846ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkeyimport java.util.HashSet; 8556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintanaimport java.util.LinkedHashMap; 866eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkeyimport java.util.List; 872f36229db823d152f3efd879e751e81a601a75b0Andy McFaddenimport java.util.Map; 88d4a1d2e14297a3387fdb5761090961e714370492Fred Quintanaimport java.util.concurrent.atomic.AtomicInteger; 89d4a1d2e14297a3387fdb5761090961e714370492Fred Quintanaimport java.util.concurrent.atomic.AtomicReference; 90603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 91603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana/** 92603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * A system service that provides account, password, and authtoken management for all 93603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * accounts on the device. Some of these calls are implemented with the help of the corresponding 94603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * {@link IAccountAuthenticator} services. This service is not accessed by users directly, 95603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * instead one uses an instance of {@link AccountManager}, which can be accessed as follows: 9646703b099516c383a6882815bcf9cd4df0ec538dBrian Carlstrom * AccountManager accountManager = AccountManager.get(context); 973326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana * @hide 98603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana */ 993ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintanapublic class AccountManagerService 1003ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintana extends IAccountManager.Stub 1015ebbb4a6b3e16f711735ae0615b9a9ea64faad38Fred Quintana implements RegisteredServicesCacheListener<AuthenticatorDescription> { 102603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String TAG = "AccountManagerService"; 103603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 104603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final int TIMEOUT_DELAY_MS = 1000 * 60; 105603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String DATABASE_NAME = "accounts.db"; 10667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani private static final int DATABASE_VERSION = 5; 107603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 108603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private final Context mContext; 109603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 11056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana private final PackageManager mPackageManager; 111258848d2ae04f447ff1c18023fa76b139fcc0862Amith Yamasani private UserManager mUserManager; 11256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 113603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private HandlerThread mMessageThread; 114603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private final MessageHandler mMessageHandler; 115603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 116603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana // Messages that can be sent on mHandler 117603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final int MESSAGE_TIMED_OUT = 3; 118603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 11956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana private final IAccountAuthenticatorCache mAuthenticatorCache; 120603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 121603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String TABLE_ACCOUNTS = "accounts"; 122603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String ACCOUNTS_ID = "_id"; 123603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String ACCOUNTS_NAME = "name"; 124603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String ACCOUNTS_TYPE = "type"; 1251cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks private static final String ACCOUNTS_TYPE_COUNT = "count(type)"; 126603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String ACCOUNTS_PASSWORD = "password"; 127603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 128603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String TABLE_AUTHTOKENS = "authtokens"; 129603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String AUTHTOKENS_ID = "_id"; 130603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String AUTHTOKENS_ACCOUNTS_ID = "accounts_id"; 131603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String AUTHTOKENS_TYPE = "type"; 132603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String AUTHTOKENS_AUTHTOKEN = "authtoken"; 133603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 134d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private static final String TABLE_GRANTS = "grants"; 135d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private static final String GRANTS_ACCOUNTS_ID = "accounts_id"; 136d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private static final String GRANTS_AUTH_TOKEN_TYPE = "auth_token_type"; 137d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private static final String GRANTS_GRANTEE_UID = "uid"; 138d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 139603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String TABLE_EXTRAS = "extras"; 140603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String EXTRAS_ID = "_id"; 141603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String EXTRAS_ACCOUNTS_ID = "accounts_id"; 142603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String EXTRAS_KEY = "key"; 143603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String EXTRAS_VALUE = "value"; 144603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 145603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String TABLE_META = "meta"; 146603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String META_KEY = "key"; 147603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String META_VALUE = "value"; 148603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 14967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani private static final String TABLE_SHARED_ACCOUNTS = "shared_accounts"; 15067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani 1511cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks private static final String[] ACCOUNT_TYPE_COUNT_PROJECTION = 1521cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks new String[] { ACCOUNTS_TYPE, ACCOUNTS_TYPE_COUNT}; 1537be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana private static final Intent ACCOUNTS_CHANGED_INTENT; 154a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 155d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private static final String COUNT_OF_MATCHING_GRANTS = "" 156d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + "SELECT COUNT(*) FROM " + TABLE_GRANTS + ", " + TABLE_ACCOUNTS 157d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + " WHERE " + GRANTS_ACCOUNTS_ID + "=" + ACCOUNTS_ID 158d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + " AND " + GRANTS_GRANTEE_UID + "=?" 159d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + " AND " + GRANTS_AUTH_TOKEN_TYPE + "=?" 160d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + " AND " + ACCOUNTS_NAME + "=?" 161d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + " AND " + ACCOUNTS_TYPE + "=?"; 162d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 16356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana private static final String SELECTION_AUTHTOKENS_BY_ACCOUNT = 16456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana AUTHTOKENS_ACCOUNTS_ID + "=(select _id FROM accounts WHERE name=? AND type=?)"; 16556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana private static final String[] COLUMNS_AUTHTOKENS_TYPE_AND_AUTHTOKEN = {AUTHTOKENS_TYPE, 16656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana AUTHTOKENS_AUTHTOKEN}; 16756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 16856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana private static final String SELECTION_USERDATA_BY_ACCOUNT = 16956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana EXTRAS_ACCOUNTS_ID + "=(select _id FROM accounts WHERE name=? AND type=?)"; 17056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana private static final String[] COLUMNS_EXTRAS_KEY_AND_VALUE = {EXTRAS_KEY, EXTRAS_VALUE}; 17156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 172a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana private final LinkedHashMap<String, Session> mSessions = new LinkedHashMap<String, Session>(); 173d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private final AtomicInteger mNotificationIds = new AtomicInteger(1); 174d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 17504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani static class UserAccounts { 17604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private final int userId; 17704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private final DatabaseHelper openHelper; 17804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private final HashMap<Pair<Pair<Account, String>, Integer>, Integer> 17904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani credentialsPermissionNotificationIds = 18004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani new HashMap<Pair<Pair<Account, String>, Integer>, Integer>(); 18104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private final HashMap<Account, Integer> signinRequiredNotificationIds = 18204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani new HashMap<Account, Integer>(); 18304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private final Object cacheLock = new Object(); 18404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani /** protected by the {@link #cacheLock} */ 185b483a99c6bdfee72fbb8fbcf893e63ef3f54658bAmith Yamasani private final HashMap<String, Account[]> accountCache = 186b483a99c6bdfee72fbb8fbcf893e63ef3f54658bAmith Yamasani new LinkedHashMap<String, Account[]>(); 18704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani /** protected by the {@link #cacheLock} */ 18804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private HashMap<Account, HashMap<String, String>> userDataCache = 18904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani new HashMap<Account, HashMap<String, String>>(); 19004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani /** protected by the {@link #cacheLock} */ 19104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private HashMap<Account, HashMap<String, String>> authTokenCache = 19204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani new HashMap<Account, HashMap<String, String>>(); 19304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani 19404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts(Context context, int userId) { 19504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani this.userId = userId; 19604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (cacheLock) { 19704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani openHelper = new DatabaseHelper(context, userId); 19804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 19904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 20004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 20104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani 20204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private final SparseArray<UserAccounts> mUsers = new SparseArray<UserAccounts>(); 20304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani 204d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private static AtomicReference<AccountManagerService> sThis = 205d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana new AtomicReference<AccountManagerService>(); 20631957f1badbb900bbfe211317e1ea992d650a72dFred Quintana private static final Account[] EMPTY_ACCOUNT_ARRAY = new Account[]{}; 2077be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana 2087be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana static { 209f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana ACCOUNTS_CHANGED_INTENT = new Intent(AccountManager.LOGIN_ACCOUNTS_CHANGED_ACTION); 2107be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana ACCOUNTS_CHANGED_INTENT.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 2117be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana } 2127be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana 21356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 214d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana /** 215d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * This should only be called by system code. One should only call this after the service 216d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * has started. 217d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * @return a reference to the AccountManagerService instance 218d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * @hide 219d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana */ 220d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana public static AccountManagerService getSingleton() { 221d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana return sThis.get(); 222d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 223603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 22456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana public AccountManagerService(Context context) { 22556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana this(context, context.getPackageManager(), new AccountAuthenticatorCache(context)); 226603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 227603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 22856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana public AccountManagerService(Context context, PackageManager packageManager, 22956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana IAccountAuthenticatorCache authenticatorCache) { 230603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mContext = context; 23156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana mPackageManager = packageManager; 232603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 233603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mMessageThread = new HandlerThread("AccountManagerService"); 234603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mMessageThread.start(); 235603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mMessageHandler = new MessageHandler(mMessageThread.getLooper()); 236603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 23756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana mAuthenticatorCache = authenticatorCache; 2385ebbb4a6b3e16f711735ae0615b9a9ea64faad38Fred Quintana mAuthenticatorCache.setListener(this, null /* Handler */); 239603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 240d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana sThis.set(this); 241afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana 242c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana IntentFilter intentFilter = new IntentFilter(); 243c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED); 244c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana intentFilter.addDataScheme("package"); 245c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana mContext.registerReceiver(new BroadcastReceiver() { 246c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana @Override 247c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana public void onReceive(Context context1, Intent intent) { 24804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani purgeOldGrantsAll(); 249c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana } 250c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana }, intentFilter); 251c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana 252135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani IntentFilter userFilter = new IntentFilter(); 253135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani userFilter.addAction(Intent.ACTION_USER_REMOVED); 25467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani userFilter.addAction(Intent.ACTION_USER_STARTED); 25567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani mContext.registerReceiverAsUser(new BroadcastReceiver() { 256135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani @Override 257135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani public void onReceive(Context context, Intent intent) { 25867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani String action = intent.getAction(); 25967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani if (Intent.ACTION_USER_REMOVED.equals(action)) { 26067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani onUserRemoved(intent); 26167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } else if (Intent.ACTION_USER_STARTED.equals(action)) { 26267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani onUserStarted(intent); 26367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 264135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani } 26567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani }, UserHandle.ALL, userFilter, null, null); 266afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana } 267afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana 26826ff6626fc4ee0ae46f01ad309b366921da589feKenny Root public void systemReady() { 26926ff6626fc4ee0ae46f01ad309b366921da589feKenny Root } 27026ff6626fc4ee0ae46f01ad309b366921da589feKenny Root 271258848d2ae04f447ff1c18023fa76b139fcc0862Amith Yamasani private UserManager getUserManager() { 272258848d2ae04f447ff1c18023fa76b139fcc0862Amith Yamasani if (mUserManager == null) { 273258848d2ae04f447ff1c18023fa76b139fcc0862Amith Yamasani mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); 274258848d2ae04f447ff1c18023fa76b139fcc0862Amith Yamasani } 275258848d2ae04f447ff1c18023fa76b139fcc0862Amith Yamasani return mUserManager; 276258848d2ae04f447ff1c18023fa76b139fcc0862Amith Yamasani } 277258848d2ae04f447ff1c18023fa76b139fcc0862Amith Yamasani 27804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private UserAccounts initUser(int userId) { 27904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (mUsers) { 28004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = mUsers.get(userId); 28104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani if (accounts == null) { 28204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts = new UserAccounts(mContext, userId); 28304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani mUsers.append(userId, accounts); 28404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani purgeOldGrants(accounts); 2856eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey validateAccountsInternal(accounts, true /* invalidateAuthenticatorCache */); 28604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 28704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani return accounts; 28804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 28904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 29004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani 29104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private void purgeOldGrantsAll() { 29204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (mUsers) { 29304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani for (int i = 0; i < mUsers.size(); i++) { 29404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani purgeOldGrants(mUsers.valueAt(i)); 29504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 29604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 29704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 29804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani 29904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private void purgeOldGrants(UserAccounts accounts) { 30004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 30104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getWritableDatabase(); 302c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana final Cursor cursor = db.query(TABLE_GRANTS, 303c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana new String[]{GRANTS_GRANTEE_UID}, 304c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana null, null, GRANTS_GRANTEE_UID, null, null); 305c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana try { 306c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana while (cursor.moveToNext()) { 307c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana final int uid = cursor.getInt(0); 308c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana final boolean packageExists = mPackageManager.getPackagesForUid(uid) != null; 309c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana if (packageExists) { 310c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana continue; 311c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana } 312c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana Log.d(TAG, "deleting grants for UID " + uid 313c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana + " because its package is no longer installed"); 314c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana db.delete(TABLE_GRANTS, GRANTS_GRANTEE_UID + "=?", 315c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana new String[]{Integer.toString(uid)}); 316c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana } 317c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana } finally { 318c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana cursor.close(); 319c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana } 320c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana } 321c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana } 322c1a4e5dc418d324f2fa2827d83002cc50e62c507Fred Quintana 3236eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey /** 3246eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey * Validate internal set of accounts against installed authenticators for 3256eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey * given user. Clears cached authenticators before validating. 3266eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey */ 3276eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey public void validateAccounts(int userId) { 3286eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey final UserAccounts accounts = getUserAccounts(userId); 3296eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey 3306eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey // Invalidate user-specific cache to make sure we catch any 3316eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey // removed authenticators. 3326eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey validateAccountsInternal(accounts, true /* invalidateAuthenticatorCache */); 3336eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey } 3346eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey 3356eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey /** 3366eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey * Validate internal set of accounts against installed authenticators for 3376eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey * given user. Clear cached authenticators before validating when requested. 3386eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey */ 3396eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey private void validateAccountsInternal( 3406eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey UserAccounts accounts, boolean invalidateAuthenticatorCache) { 3416eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey if (invalidateAuthenticatorCache) { 3426eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey mAuthenticatorCache.invalidateCache(accounts.userId); 3436eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey } 3446eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey 3456ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey final HashSet<AuthenticatorDescription> knownAuth = Sets.newHashSet(); 3466ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey for (RegisteredServicesCache.ServiceInfo<AuthenticatorDescription> service : 3476ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey mAuthenticatorCache.getAllServices(accounts.userId)) { 3486ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey knownAuth.add(service.type); 3496ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey } 3506ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey 35104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 35204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getWritableDatabase(); 353f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana boolean accountDeleted = false; 354f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana Cursor cursor = db.query(TABLE_ACCOUNTS, 355f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana new String[]{ACCOUNTS_ID, ACCOUNTS_TYPE, ACCOUNTS_NAME}, 356f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana null, null, null, null, null); 357f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana try { 35804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.accountCache.clear(); 35956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final HashMap<String, ArrayList<String>> accountNamesByType = 360b483a99c6bdfee72fbb8fbcf893e63ef3f54658bAmith Yamasani new LinkedHashMap<String, ArrayList<String>>(); 36156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana while (cursor.moveToNext()) { 36256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final long accountId = cursor.getLong(0); 36356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final String accountType = cursor.getString(1); 36456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final String accountName = cursor.getString(2); 3656ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey 3666ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey if (!knownAuth.contains(AuthenticatorDescription.newKey(accountType))) { 3676eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey Slog.w(TAG, "deleting account " + accountName + " because type " 36856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + accountType + " no longer has a registered authenticator"); 36956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana db.delete(TABLE_ACCOUNTS, ACCOUNTS_ID + "=" + accountId, null); 37056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana accountDeleted = true; 37156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final Account account = new Account(accountName, accountType); 37204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.userDataCache.remove(account); 37304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.authTokenCache.remove(account); 37456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } else { 37556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana ArrayList<String> accountNames = accountNamesByType.get(accountType); 37656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (accountNames == null) { 37756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana accountNames = new ArrayList<String>(); 37856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana accountNamesByType.put(accountType, accountNames); 37956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 38056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana accountNames.add(accountName); 38156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 38256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 3832f36229db823d152f3efd879e751e81a601a75b0Andy McFadden for (Map.Entry<String, ArrayList<String>> cur 384f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana : accountNamesByType.entrySet()) { 38556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final String accountType = cur.getKey(); 38656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final ArrayList<String> accountNames = cur.getValue(); 38756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final Account[] accountsForType = new Account[accountNames.size()]; 38856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana int i = 0; 38956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana for (String accountName : accountNames) { 39056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana accountsForType[i] = new Account(accountName, accountType); 39156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana ++i; 39256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 39304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.accountCache.put(accountType, accountsForType); 394afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana } 395f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } finally { 396f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana cursor.close(); 397f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (accountDeleted) { 39804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani sendAccountsChangedBroadcast(accounts.userId); 399f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 400afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana } 401afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana } 4023ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintana } 4033ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintana 40404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private UserAccounts getUserAccountsForCaller() { 405f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackborn return getUserAccounts(UserHandle.getCallingUserId()); 40604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 40704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani 40804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani protected UserAccounts getUserAccounts(int userId) { 40904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (mUsers) { 41004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = mUsers.get(userId); 41104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani if (accounts == null) { 41204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts = initUser(userId); 41304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani mUsers.append(userId, accounts); 41404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 41504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani return accounts; 41604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 41704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 41804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani 419135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani private void onUserRemoved(Intent intent) { 4202a00329c6d55c6cd9166e01963d7410e95d80d21Amith Yamasani int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); 421135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani if (userId < 1) return; 422135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani 423135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani UserAccounts accounts; 424135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani synchronized (mUsers) { 425135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani accounts = mUsers.get(userId); 426135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani mUsers.remove(userId); 427135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani } 428135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani if (accounts == null) { 429135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani File dbFile = new File(getDatabaseName(userId)); 430135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani dbFile.delete(); 431135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani return; 432135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani } 433135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani 434135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani synchronized (accounts.cacheLock) { 435135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani accounts.openHelper.close(); 436135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani File dbFile = new File(getDatabaseName(userId)); 437135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani dbFile.delete(); 438135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani } 439135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani } 440135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani 44167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani private void onUserStarted(Intent intent) { 44267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); 44367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani if (userId < 1) return; 44467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani 44567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani // Check if there's a shared account that needs to be created as an account 44667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani Account[] sharedAccounts = getSharedAccountsAsUser(userId); 44767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani if (sharedAccounts == null || sharedAccounts.length == 0) return; 44867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani Account[] accounts = getAccountsAsUser(null, userId); 44967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani for (Account sa : sharedAccounts) { 45067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani if (ArrayUtils.contains(accounts, sa)) continue; 45167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani // Account doesn't exist. Copy it now. 45267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani copyAccountToUser(sa, UserHandle.USER_OWNER, userId); 45367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 45467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 45567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani 4566ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey @Override 4576ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey public void onServiceChanged(AuthenticatorDescription desc, int userId, boolean removed) { 4586eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey validateAccountsInternal(getUserAccounts(userId), false /* invalidateAuthenticatorCache */); 459603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 460603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 461a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public String getPassword(Account account) { 46256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 46356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "getPassword: " + account 46456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 46556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 46656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 467382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 468d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkAuthenticateAccountsPermission(account); 469d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 47004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 47126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 472603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana try { 47304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani return readPasswordInternal(accounts, account); 474603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } finally { 47526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 476603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 477603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 478603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 47904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private String readPasswordInternal(UserAccounts accounts, Account account) { 48031957f1badbb900bbfe211317e1ea992d650a72dFred Quintana if (account == null) { 48131957f1badbb900bbfe211317e1ea992d650a72dFred Quintana return null; 48231957f1badbb900bbfe211317e1ea992d650a72dFred Quintana } 48331957f1badbb900bbfe211317e1ea992d650a72dFred Quintana 48404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 48504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getReadableDatabase(); 486f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana Cursor cursor = db.query(TABLE_ACCOUNTS, new String[]{ACCOUNTS_PASSWORD}, 487f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?", 488f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana new String[]{account.name, account.type}, null, null, null); 489f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana try { 490f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (cursor.moveToNext()) { 491f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return cursor.getString(0); 492f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 493f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return null; 494f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } finally { 495f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana cursor.close(); 496ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 497ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 498ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 499ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 500a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public String getUserData(Account account, String key) { 50156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 50256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "getUserData: " + account 50356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", key " + key 50456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 50556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 50656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 507382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 508382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (key == null) throw new IllegalArgumentException("key is null"); 509d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkAuthenticateAccountsPermission(account); 51004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 51126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 512603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana try { 51304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani return readUserDataInternal(accounts, account, key); 514ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } finally { 515ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana restoreCallingIdentity(identityToken); 516ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 517ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 518ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 5199788976b1465ce982b5ae7c741345edd0ecd9322Fred Quintana public AuthenticatorDescription[] getAuthenticatorTypes() { 52056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 52156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "getAuthenticatorTypes: " 52256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + "caller's uid " + Binder.getCallingUid() 52356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 52456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 5256ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey final int userId = UserHandle.getCallingUserId(); 5266ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey final long identityToken = clearCallingIdentity(); 52726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 5289788976b1465ce982b5ae7c741345edd0ecd9322Fred Quintana Collection<AccountAuthenticatorCache.ServiceInfo<AuthenticatorDescription>> 5296ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey authenticatorCollection = mAuthenticatorCache.getAllServices(userId); 5309788976b1465ce982b5ae7c741345edd0ecd9322Fred Quintana AuthenticatorDescription[] types = 5319788976b1465ce982b5ae7c741345edd0ecd9322Fred Quintana new AuthenticatorDescription[authenticatorCollection.size()]; 53226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana int i = 0; 5339788976b1465ce982b5ae7c741345edd0ecd9322Fred Quintana for (AccountAuthenticatorCache.ServiceInfo<AuthenticatorDescription> authenticator 534718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana : authenticatorCollection) { 535718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana types[i] = authenticator.type; 53626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana i++; 53726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 53826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana return types; 53926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 54026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 541a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 542a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 543a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 5443df7d697ca86ee2081bcfba31bcbd3ae4f4bcdf8Jatin Lodhia @Override 545a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public boolean addAccount(Account account, String password, Bundle extras) { 54656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 54756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "addAccount: " + account 54856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 54956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 55056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 551382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 552d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkAuthenticateAccountsPermission(account); 5533df7d697ca86ee2081bcfba31bcbd3ae4f4bcdf8Jatin Lodhia /* 5543df7d697ca86ee2081bcfba31bcbd3ae4f4bcdf8Jatin Lodhia * Child users are not allowed to add accounts. Only the accounts that are 5553df7d697ca86ee2081bcfba31bcbd3ae4f4bcdf8Jatin Lodhia * shared by the parent profile can be added to child profile. 5563df7d697ca86ee2081bcfba31bcbd3ae4f4bcdf8Jatin Lodhia * 5573df7d697ca86ee2081bcfba31bcbd3ae4f4bcdf8Jatin Lodhia * TODO: Only allow accounts that were shared to be added by 5583df7d697ca86ee2081bcfba31bcbd3ae4f4bcdf8Jatin Lodhia * a limited user. 5593df7d697ca86ee2081bcfba31bcbd3ae4f4bcdf8Jatin Lodhia */ 560d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 56104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 562603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana // fails if the account already exists 56326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 564603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana try { 56567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani return addAccountInternal(accounts, account, password, extras, false); 56667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } finally { 56767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani restoreCallingIdentity(identityToken); 56867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 56967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 57067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani 57167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani private boolean copyAccountToUser(final Account account, int userFrom, int userTo) { 57267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani final UserAccounts fromAccounts = getUserAccounts(userFrom); 57367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani final UserAccounts toAccounts = getUserAccounts(userTo); 57467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani if (fromAccounts == null || toAccounts == null) { 57567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani return false; 57667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 57767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani 57867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani long identityToken = clearCallingIdentity(); 57967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani try { 58067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani new Session(fromAccounts, null, account.type, false, 58167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani false /* stripAuthTokenFromResult */) { 58267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani protected String toDebugString(long now) { 58367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani return super.toDebugString(now) + ", getAccountCredentialsForClone" 58467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani + ", " + account.type; 58567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 58667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani 58767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani public void run() throws RemoteException { 58867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani mAuthenticator.getAccountCredentialsForCloning(this, account); 58967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 59067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani 59167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani public void onResult(Bundle result) { 59267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani if (result != null) { 59367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani if (result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT, false)) { 59467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani // Create a Session for the target user and pass in the bundle 59567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani completeCloningAccount(result, account, toAccounts); 59667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 59767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani return; 59867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } else { 59967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani super.onResult(result); 60067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 60167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 60267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani }.bind(); 603ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } finally { 604ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana restoreCallingIdentity(identityToken); 605ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 60667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani return true; 60767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 60867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani 60967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani void completeCloningAccount(final Bundle result, final Account account, 61067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani final UserAccounts targetUser) { 61167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani long id = clearCallingIdentity(); 61267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani try { 61367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani new Session(targetUser, null, account.type, false, 61467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani false /* stripAuthTokenFromResult */) { 61567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani protected String toDebugString(long now) { 61667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani return super.toDebugString(now) + ", getAccountCredentialsForClone" 61767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani + ", " + account.type; 61867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 61967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani 62067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani public void run() throws RemoteException { 62167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani mAuthenticator.addAccountFromCredentials(this, account, result); 62267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 62367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani 62467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani public void onResult(Bundle result) { 62567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani if (result != null) { 62667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani if (result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT, false)) { 62767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani // TODO: Anything? 62867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } else { 62967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani // TODO: Show error notification 63067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani // TODO: Should we remove the shadow account to avoid retries? 63167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 63267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani return; 63367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } else { 63467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani super.onResult(result); 63567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 63667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 63767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani 63867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani public void onError(int errorCode, String errorMessage) { 63967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani super.onError(errorCode, errorMessage); 64067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani // TODO: Show error notification to user 64167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani // TODO: Should we remove the shadow account so that it doesn't keep trying? 64267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 64367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani 64467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani }.bind(); 64567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } finally { 64667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani restoreCallingIdentity(id); 64767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 648ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 649ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 65004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private boolean addAccountInternal(UserAccounts accounts, Account account, String password, 65167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani Bundle extras, boolean restricted) { 652743dfad2a51e016ddb741c104317637089187753Fred Quintana if (account == null) { 653743dfad2a51e016ddb741c104317637089187753Fred Quintana return false; 654743dfad2a51e016ddb741c104317637089187753Fred Quintana } 65504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 65604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getWritableDatabase(); 657f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.beginTransaction(); 658f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana try { 659f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana long numMatches = DatabaseUtils.longForQuery(db, 660f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana "select count(*) from " + TABLE_ACCOUNTS 661f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana + " WHERE " + ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?", 662f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana new String[]{account.name, account.type}); 663f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (numMatches > 0) { 664f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana Log.w(TAG, "insertAccountIntoDatabase: " + account 665f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana + ", skipping since the account already exists"); 666f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return false; 667f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 668f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana ContentValues values = new ContentValues(); 669f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana values.put(ACCOUNTS_NAME, account.name); 670f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana values.put(ACCOUNTS_TYPE, account.type); 671f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana values.put(ACCOUNTS_PASSWORD, password); 672f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana long accountId = db.insert(TABLE_ACCOUNTS, ACCOUNTS_NAME, values); 673f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (accountId < 0) { 674f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana Log.w(TAG, "insertAccountIntoDatabase: " + account 675f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana + ", skipping the DB insert failed"); 676f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return false; 677f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 678f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (extras != null) { 679f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana for (String key : extras.keySet()) { 680f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana final String value = extras.getString(key); 681f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (insertExtraLocked(db, accountId, key, value) < 0) { 682f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana Log.w(TAG, "insertAccountIntoDatabase: " + account 683f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana + ", skipping since insertExtra failed for key " + key); 684f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return false; 685f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 686603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 687603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 688f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.setTransactionSuccessful(); 68904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani insertAccountIntoCacheLocked(accounts, account); 690f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } finally { 691f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.endTransaction(); 692603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 69304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani sendAccountsChangedBroadcast(accounts.userId); 694f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return true; 695603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 696603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 697603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 698f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana private long insertExtraLocked(SQLiteDatabase db, long accountId, String key, String value) { 699603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana ContentValues values = new ContentValues(); 700603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana values.put(EXTRAS_KEY, key); 701603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana values.put(EXTRAS_ACCOUNTS_ID, accountId); 702603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana values.put(EXTRAS_VALUE, value); 703603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana return db.insert(TABLE_EXTRAS, EXTRAS_KEY, values); 704603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 705603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 7063084a6f80180506ce26fe4773d9a19f004b7f625Fred Quintana public void hasFeatures(IAccountManagerResponse response, 707bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana Account account, String[] features) { 70856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 70956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "hasFeatures: " + account 71056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", response " + response 71156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", features " + stringArrayToString(features) 71256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 71356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 71456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 715382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (response == null) throw new IllegalArgumentException("response is null"); 716382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 717382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (features == null) throw new IllegalArgumentException("features is null"); 718bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana checkReadAccountsPermission(); 71904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 720bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana long identityToken = clearCallingIdentity(); 721bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana try { 72204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani new TestFeaturesSession(accounts, response, account, features).bind(); 723bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } finally { 724bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana restoreCallingIdentity(identityToken); 725bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 726bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 727bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana 728bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana private class TestFeaturesSession extends Session { 729bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana private final String[] mFeatures; 730bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana private final Account mAccount; 731bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana 73204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani public TestFeaturesSession(UserAccounts accounts, IAccountManagerResponse response, 733bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana Account account, String[] features) { 73404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani super(accounts, response, account.type, false /* expectActivityLaunch */, 7358570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana true /* stripAuthTokenFromResult */); 736bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana mFeatures = features; 737bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana mAccount = account; 738bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 739bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana 740bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana public void run() throws RemoteException { 741bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana try { 742bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana mAuthenticator.hasFeatures(this, mAccount, mFeatures); 743bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } catch (RemoteException e) { 744bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana onError(AccountManager.ERROR_CODE_REMOTE_EXCEPTION, "remote exception"); 745bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 746bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 747bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana 748bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana public void onResult(Bundle result) { 749bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana IAccountManagerResponse response = getResponseAndClose(); 750bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana if (response != null) { 751bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana try { 752bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana if (result == null) { 753166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana response.onError(AccountManager.ERROR_CODE_INVALID_RESPONSE, "null bundle"); 754bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana return; 755bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 75656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 75756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, getClass().getSimpleName() + " calling onResult() on response " 75856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + response); 75956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 760bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana final Bundle newResult = new Bundle(); 761bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana newResult.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, 762bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT, false)); 763bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana response.onResult(newResult); 764bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } catch (RemoteException e) { 765bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana // if the caller is dead then there is no one to care about remote exceptions 766bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 767bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana Log.v(TAG, "failure while notifying response", e); 768bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 769bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 770bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 771bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 772bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana 773bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana protected String toDebugString(long now) { 7743084a6f80180506ce26fe4773d9a19f004b7f625Fred Quintana return super.toDebugString(now) + ", hasFeatures" 775bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana + ", " + mAccount 776bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana + ", " + (mFeatures != null ? TextUtils.join(",", mFeatures) : null); 777bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 778bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 779307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana 780ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana public void removeAccount(IAccountManagerResponse response, Account account) { 78156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 78256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "removeAccount: " + account 78356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", response " + response 78456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 78556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 78656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 787382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (response == null) throw new IllegalArgumentException("response is null"); 788382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 789d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkManageAccountsPermission(); 79050cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn UserHandle user = Binder.getCallingUserHandle(); 79104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 792e4cf73437a18c1444055f88a1fcc0d146ec23ac5Amith Yamasani if (!canUserModifyAccounts(Binder.getCallingUid())) { 793e4cf73437a18c1444055f88a1fcc0d146ec23ac5Amith Yamasani try { 794e4cf73437a18c1444055f88a1fcc0d146ec23ac5Amith Yamasani response.onError(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION, 795e4cf73437a18c1444055f88a1fcc0d146ec23ac5Amith Yamasani "User cannot modify accounts"); 796e4cf73437a18c1444055f88a1fcc0d146ec23ac5Amith Yamasani } catch (RemoteException re) { 797e4cf73437a18c1444055f88a1fcc0d146ec23ac5Amith Yamasani } 798e4cf73437a18c1444055f88a1fcc0d146ec23ac5Amith Yamasani } 799e4cf73437a18c1444055f88a1fcc0d146ec23ac5Amith Yamasani 80026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 801ec0c4f4183630a64c2b2cc8f961dc7e11cc628caCostin Manolache 80250cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn cancelNotification(getSigninRequiredNotificationId(accounts, account), user); 80304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized(accounts.credentialsPermissionNotificationIds) { 804ec0c4f4183630a64c2b2cc8f961dc7e11cc628caCostin Manolache for (Pair<Pair<Account, String>, Integer> pair: 80504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.credentialsPermissionNotificationIds.keySet()) { 806ec0c4f4183630a64c2b2cc8f961dc7e11cc628caCostin Manolache if (account.equals(pair.first.first)) { 80704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani int id = accounts.credentialsPermissionNotificationIds.get(pair); 80850cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn cancelNotification(id, user); 809ec0c4f4183630a64c2b2cc8f961dc7e11cc628caCostin Manolache } 810ec0c4f4183630a64c2b2cc8f961dc7e11cc628caCostin Manolache } 811ec0c4f4183630a64c2b2cc8f961dc7e11cc628caCostin Manolache } 812ec0c4f4183630a64c2b2cc8f961dc7e11cc628caCostin Manolache 81326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 81404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani new RemoveAccountSession(accounts, response, account).bind(); 81526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 81626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 817a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 818603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 819603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 820ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana private class RemoveAccountSession extends Session { 821ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana final Account mAccount; 82204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani public RemoveAccountSession(UserAccounts accounts, IAccountManagerResponse response, 82304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani Account account) { 82404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani super(accounts, response, account.type, false /* expectActivityLaunch */, 8258570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana true /* stripAuthTokenFromResult */); 826ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana mAccount = account; 827ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 828ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 829ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana protected String toDebugString(long now) { 830ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana return super.toDebugString(now) + ", removeAccount" 831ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana + ", account " + mAccount; 832ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 833ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 834ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana public void run() throws RemoteException { 835ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana mAuthenticator.getAccountRemovalAllowed(this, mAccount); 836ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 837ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 838ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana public void onResult(Bundle result) { 839f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana if (result != null && result.containsKey(AccountManager.KEY_BOOLEAN_RESULT) 840f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana && !result.containsKey(AccountManager.KEY_INTENT)) { 841f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana final boolean removalAllowed = result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT); 842ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana if (removalAllowed) { 84304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani removeAccountInternal(mAccounts, mAccount); 844ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 845ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana IAccountManagerResponse response = getResponseAndClose(); 846ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana if (response != null) { 84756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 84856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, getClass().getSimpleName() + " calling onResult() on response " 84956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + response); 85056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 851ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana Bundle result2 = new Bundle(); 852f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana result2.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, removalAllowed); 853ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana try { 854ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana response.onResult(result2); 855ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } catch (RemoteException e) { 856ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana // ignore 857ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 858ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 859ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 860ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana super.onResult(result); 861ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 862ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 863ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 86404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani /* For testing */ 865f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana protected void removeAccountInternal(Account account) { 86604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani removeAccountInternal(getUserAccountsForCaller(), account); 86704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 86804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani 86904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private void removeAccountInternal(UserAccounts accounts, Account account) { 87004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 87104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getWritableDatabase(); 872f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.delete(TABLE_ACCOUNTS, ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?", 873f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana new String[]{account.name, account.type}); 87404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani removeAccountFromCacheLocked(accounts, account); 87504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani sendAccountsChangedBroadcast(accounts.userId); 876f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 87767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani if (accounts.userId == UserHandle.USER_OWNER) { 87867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani // Owner's account was removed, remove from any users that are sharing 87967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani // this account. 88067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani long id = Binder.clearCallingIdentity(); 88167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani try { 88267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani List<UserInfo> users = mUserManager.getUsers(true); 88367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani for (UserInfo user : users) { 88467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani if (!user.isPrimary() && user.isRestricted()) { 88567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani removeSharedAccountAsUser(account, user.id); 88667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 88767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 88867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } finally { 88967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani Binder.restoreCallingIdentity(id); 89067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 89167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 892ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 893ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 894a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void invalidateAuthToken(String accountType, String authToken) { 89556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 89656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "invalidateAuthToken: accountType " + accountType 89756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 89856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 89956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 900382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (accountType == null) throw new IllegalArgumentException("accountType is null"); 901382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (authToken == null) throw new IllegalArgumentException("authToken is null"); 902b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana checkManageAccountsOrUseCredentialsPermissions(); 90304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 90426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 905603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana try { 90604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 90704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getWritableDatabase(); 908f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.beginTransaction(); 909f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana try { 91004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani invalidateAuthTokenLocked(accounts, db, accountType, authToken); 911f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.setTransactionSuccessful(); 912f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } finally { 913f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.endTransaction(); 914f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 91526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 916603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } finally { 91726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 918603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 919603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 920603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 92104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private void invalidateAuthTokenLocked(UserAccounts accounts, SQLiteDatabase db, 92204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani String accountType, String authToken) { 923ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana if (authToken == null || accountType == null) { 924ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana return; 925ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 9263326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana Cursor cursor = db.rawQuery( 9273326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana "SELECT " + TABLE_AUTHTOKENS + "." + AUTHTOKENS_ID 9283326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + ", " + TABLE_ACCOUNTS + "." + ACCOUNTS_NAME 9293326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + ", " + TABLE_AUTHTOKENS + "." + AUTHTOKENS_TYPE 9303326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + " FROM " + TABLE_ACCOUNTS 9313326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + " JOIN " + TABLE_AUTHTOKENS 9323326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + " ON " + TABLE_ACCOUNTS + "." + ACCOUNTS_ID 9333326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + " = " + AUTHTOKENS_ACCOUNTS_ID 9343326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + " WHERE " + AUTHTOKENS_AUTHTOKEN + " = ? AND " 9353326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + TABLE_ACCOUNTS + "." + ACCOUNTS_TYPE + " = ?", 9363326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana new String[]{authToken, accountType}); 9373326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana try { 9383326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana while (cursor.moveToNext()) { 9393326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana long authTokenId = cursor.getLong(0); 9403326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana String accountName = cursor.getString(1); 9413326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana String authTokenType = cursor.getString(2); 9423326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana db.delete(TABLE_AUTHTOKENS, AUTHTOKENS_ID + "=" + authTokenId, null); 94304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani writeAuthTokenIntoCacheLocked(accounts, db, new Account(accountName, accountType), 944f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana authTokenType, null); 945603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 9463326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } finally { 9473326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana cursor.close(); 948603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 949603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 950603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 95104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private boolean saveAuthTokenToDatabase(UserAccounts accounts, Account account, String type, 95204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani String authToken) { 95331957f1badbb900bbfe211317e1ea992d650a72dFred Quintana if (account == null || type == null) { 95431957f1badbb900bbfe211317e1ea992d650a72dFred Quintana return false; 95531957f1badbb900bbfe211317e1ea992d650a72dFred Quintana } 95650cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn cancelNotification(getSigninRequiredNotificationId(accounts, account), 95750cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn new UserHandle(accounts.userId)); 95804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 95904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getWritableDatabase(); 960f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.beginTransaction(); 961f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana try { 962f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana long accountId = getAccountIdLocked(db, account); 963f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (accountId < 0) { 964f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return false; 965f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 966f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.delete(TABLE_AUTHTOKENS, 967f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana AUTHTOKENS_ACCOUNTS_ID + "=" + accountId + " AND " + AUTHTOKENS_TYPE + "=?", 968f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana new String[]{type}); 969f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana ContentValues values = new ContentValues(); 970f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana values.put(AUTHTOKENS_ACCOUNTS_ID, accountId); 971f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana values.put(AUTHTOKENS_TYPE, type); 972f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana values.put(AUTHTOKENS_AUTHTOKEN, authToken); 973f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (db.insert(TABLE_AUTHTOKENS, AUTHTOKENS_AUTHTOKEN, values) >= 0) { 974f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.setTransactionSuccessful(); 97504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani writeAuthTokenIntoCacheLocked(accounts, db, account, type, authToken); 976f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return true; 977f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 9783326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana return false; 979f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } finally { 980f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.endTransaction(); 9813326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 982603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 983603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 984603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 985a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public String peekAuthToken(Account account, String authTokenType) { 98656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 98756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "peekAuthToken: " + account 98856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", authTokenType " + authTokenType 98956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 99056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 99156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 992382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 993382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null"); 994d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkAuthenticateAccountsPermission(account); 99504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 99626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 99726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 99804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani return readAuthTokenInternal(accounts, account, authTokenType); 99926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 100026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 1001603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1002603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1003603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1004a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void setAuthToken(Account account, String authTokenType, String authToken) { 100556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 100656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "setAuthToken: " + account 100756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", authTokenType " + authTokenType 100856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 100956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 101056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 1011382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 1012382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null"); 1013d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkAuthenticateAccountsPermission(account); 101404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 101526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 101626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 101704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani saveAuthTokenToDatabase(accounts, account, authTokenType, authToken); 101826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 101926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 102026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1021603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1022603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1023a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void setPassword(Account account, String password) { 102456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 102556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "setAuthToken: " + account 102656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 102756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 102856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 1029382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 1030d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkAuthenticateAccountsPermission(account); 103104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 103226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 103326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 103404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani setPasswordInternal(accounts, account, password); 103526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 103626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 103726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1038603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1039603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 104004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private void setPasswordInternal(UserAccounts accounts, Account account, String password) { 104131957f1badbb900bbfe211317e1ea992d650a72dFred Quintana if (account == null) { 104231957f1badbb900bbfe211317e1ea992d650a72dFred Quintana return; 104331957f1badbb900bbfe211317e1ea992d650a72dFred Quintana } 104404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 104504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getWritableDatabase(); 1046f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.beginTransaction(); 1047f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana try { 1048f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana final ContentValues values = new ContentValues(); 1049f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana values.put(ACCOUNTS_PASSWORD, password); 1050f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana final long accountId = getAccountIdLocked(db, account); 1051f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (accountId >= 0) { 1052f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana final String[] argsAccountId = {String.valueOf(accountId)}; 1053f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.update(TABLE_ACCOUNTS, values, ACCOUNTS_ID + "=?", argsAccountId); 1054f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.delete(TABLE_AUTHTOKENS, AUTHTOKENS_ACCOUNTS_ID + "=?", argsAccountId); 105504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.authTokenCache.remove(account); 1056f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.setTransactionSuccessful(); 1057f5ffe89e736caee1419f0acb469565d5100b8fb8Costin Manolache } 1058f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } finally { 1059f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.endTransaction(); 1060d4a9d6c42bb412e27a8383aaacd051419d98a662Fred Quintana } 106104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani sendAccountsChangedBroadcast(accounts.userId); 1062d4a9d6c42bb412e27a8383aaacd051419d98a662Fred Quintana } 10633ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintana } 10643ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintana 106504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private void sendAccountsChangedBroadcast(int userId) { 106656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.i(TAG, "the accounts changed, sending broadcast of " 106756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ACCOUNTS_CHANGED_INTENT.getAction()); 106879af1dd54c16cde063152922b42c96d72ae9eca8Dianne Hackborn mContext.sendBroadcastAsUser(ACCOUNTS_CHANGED_INTENT, new UserHandle(userId)); 10693326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 10703326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 1071a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void clearPassword(Account account) { 107256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 107356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "clearPassword: " + account 107456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 107556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 107656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 1077382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 1078d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkManageAccountsPermission(); 107904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 108026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 108126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 108204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani setPasswordInternal(accounts, account, null); 108326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 108426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 108526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1086603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1087603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1088a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void setUserData(Account account, String key, String value) { 108956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 109056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "setUserData: " + account 109156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", key " + key 109256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 109356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 109456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 1095382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (key == null) throw new IllegalArgumentException("key is null"); 1096382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 1097d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkAuthenticateAccountsPermission(account); 109804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 109926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 1100603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana try { 110104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani setUserdataInternal(accounts, account, key, value); 1102ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } finally { 1103ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana restoreCallingIdentity(identityToken); 1104ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 1105ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 1106ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 110704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private void setUserdataInternal(UserAccounts accounts, Account account, String key, 110804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani String value) { 110931957f1badbb900bbfe211317e1ea992d650a72dFred Quintana if (account == null || key == null) { 111031957f1badbb900bbfe211317e1ea992d650a72dFred Quintana return; 111131957f1badbb900bbfe211317e1ea992d650a72dFred Quintana } 111204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 111304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getWritableDatabase(); 1114f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.beginTransaction(); 1115f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana try { 1116f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana long accountId = getAccountIdLocked(db, account); 1117f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (accountId < 0) { 1118ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana return; 111926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1120f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana long extrasId = getExtrasIdLocked(db, accountId, key); 1121f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (extrasId < 0 ) { 1122f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana extrasId = insertExtraLocked(db, accountId, key, value); 1123f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (extrasId < 0) { 1124f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return; 1125f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 1126f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } else { 1127f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana ContentValues values = new ContentValues(); 1128f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana values.put(EXTRAS_VALUE, value); 1129f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (1 != db.update(TABLE_EXTRAS, values, EXTRAS_ID + "=" + extrasId, null)) { 1130f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return; 1131f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 1132ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 1133f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 113404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani writeUserDataIntoCacheLocked(accounts, db, account, key, value); 1135f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.setTransactionSuccessful(); 1136f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } finally { 1137f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.endTransaction(); 1138603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1139603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1140603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1141603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1142d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private void onResult(IAccountManagerResponse response, Bundle result) { 114356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (result == null) { 114456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.e(TAG, "the result is unexpectedly null", new Exception()); 114556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 114656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 114756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, getClass().getSimpleName() + " calling onResult() on response " 114856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + response); 114956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 1150d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana try { 1151d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana response.onResult(result); 1152d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } catch (RemoteException e) { 1153d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana // if the caller is dead then there is no one to care about remote 1154d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana // exceptions 1155d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 1156d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Log.v(TAG, "failure while notifying response", e); 1157d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1158d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1159d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1160d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 1161d9640ec712806508877868d08aafaa2d715ff441Fred Quintana public void getAuthTokenLabel(IAccountManagerResponse response, final String accountType, 1162d9640ec712806508877868d08aafaa2d715ff441Fred Quintana final String authTokenType) 1163d9640ec712806508877868d08aafaa2d715ff441Fred Quintana throws RemoteException { 1164d9640ec712806508877868d08aafaa2d715ff441Fred Quintana if (accountType == null) throw new IllegalArgumentException("accountType is null"); 11655f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null"); 11665f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache 1167d9640ec712806508877868d08aafaa2d715ff441Fred Quintana final int callingUid = getCallingUid(); 1168d9640ec712806508877868d08aafaa2d715ff441Fred Quintana clearCallingIdentity(); 1169d9640ec712806508877868d08aafaa2d715ff441Fred Quintana if (callingUid != android.os.Process.SYSTEM_UID) { 1170d9640ec712806508877868d08aafaa2d715ff441Fred Quintana throw new SecurityException("can only call from system"); 1171d9640ec712806508877868d08aafaa2d715ff441Fred Quintana } 1172f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackborn UserAccounts accounts = getUserAccounts(UserHandle.getUserId(callingUid)); 11735f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache long identityToken = clearCallingIdentity(); 11745f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache try { 1175d9640ec712806508877868d08aafaa2d715ff441Fred Quintana new Session(accounts, response, accountType, false, 11765f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache false /* stripAuthTokenFromResult */) { 11775f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache protected String toDebugString(long now) { 11785f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache return super.toDebugString(now) + ", getAuthTokenLabel" 1179d9640ec712806508877868d08aafaa2d715ff441Fred Quintana + ", " + accountType 11805f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache + ", authTokenType " + authTokenType; 11815f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache } 11825f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache 11835f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache public void run() throws RemoteException { 11845f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache mAuthenticator.getAuthTokenLabel(this, authTokenType); 11855f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache } 11865f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache 11875f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache public void onResult(Bundle result) { 11885f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache if (result != null) { 11895f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache String label = result.getString(AccountManager.KEY_AUTH_TOKEN_LABEL); 11905f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache Bundle bundle = new Bundle(); 11915f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache bundle.putString(AccountManager.KEY_AUTH_TOKEN_LABEL, label); 11925f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache super.onResult(bundle); 11935f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache return; 11945f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache } else { 11955f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache super.onResult(result); 11965f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache } 11975f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache } 11985f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache }.bind(); 11995f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache } finally { 12005f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache restoreCallingIdentity(identityToken); 12015f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache } 12025f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache } 12035f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache 1204a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void getAuthToken(IAccountManagerResponse response, final Account account, 1205a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana final String authTokenType, final boolean notifyOnAuthFailure, 1206c6684f9e9790e92960504e9b32f20f27003d9f37Costin Manolache final boolean expectActivityLaunch, Bundle loginOptionsIn) { 120756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 120856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "getAuthToken: " + account 120956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", response " + response 121056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", authTokenType " + authTokenType 121156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", notifyOnAuthFailure " + notifyOnAuthFailure 121256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", expectActivityLaunch " + expectActivityLaunch 121356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 121456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 121556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 1216382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (response == null) throw new IllegalArgumentException("response is null"); 1217382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 1218382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null"); 1219d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkBinderPermission(Manifest.permission.USE_CREDENTIALS); 12204120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn final UserAccounts accounts = getUserAccountsForCaller(); 12216ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey final RegisteredServicesCache.ServiceInfo<AuthenticatorDescription> authenticatorInfo; 12226ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey authenticatorInfo = mAuthenticatorCache.getServiceInfo( 12236ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey AuthenticatorDescription.newKey(account.type), accounts.userId); 1224a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache final boolean customTokens = 1225a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache authenticatorInfo != null && authenticatorInfo.type.customTokens; 1226a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache 1227a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache // skip the check if customTokens 1228b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache final int callerUid = Binder.getCallingUid(); 1229a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache final boolean permissionGranted = customTokens || 1230a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache permissionIsGranted(account, authTokenType, callerUid); 1231a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache 1232c6684f9e9790e92960504e9b32f20f27003d9f37Costin Manolache final Bundle loginOptions = (loginOptionsIn == null) ? new Bundle() : 1233c6684f9e9790e92960504e9b32f20f27003d9f37Costin Manolache loginOptionsIn; 1234b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache // let authenticator know the identity of the caller 1235b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache loginOptions.putInt(AccountManager.KEY_CALLER_UID, callerUid); 1236b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache loginOptions.putInt(AccountManager.KEY_CALLER_PID, Binder.getCallingPid()); 1237b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache if (notifyOnAuthFailure) { 1238b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache loginOptions.putBoolean(AccountManager.KEY_NOTIFY_ON_FAILURE, true); 1239a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache } 12406ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey 124126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 124226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 1243d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana // if the caller has permission, do the peek. otherwise go the more expensive 1244d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana // route of starting a Session 1245a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache if (!customTokens && permissionGranted) { 124604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani String authToken = readAuthTokenInternal(accounts, account, authTokenType); 1247d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (authToken != null) { 124826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana Bundle result = new Bundle(); 1249f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana result.putString(AccountManager.KEY_AUTHTOKEN, authToken); 1250f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name); 1251f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana result.putString(AccountManager.KEY_ACCOUNT_TYPE, account.type); 1252d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana onResult(response, result); 1253d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana return; 1254a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1255a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1256603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 125704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani new Session(accounts, response, account.type, expectActivityLaunch, 12588570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana false /* stripAuthTokenFromResult */) { 125926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana protected String toDebugString(long now) { 126026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana if (loginOptions != null) loginOptions.keySet(); 126126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana return super.toDebugString(now) + ", getAuthToken" 126226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana + ", " + account 126326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana + ", authTokenType " + authTokenType 126426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana + ", loginOptions " + loginOptions 126526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana + ", notifyOnAuthFailure " + notifyOnAuthFailure; 126626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1267a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 126826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana public void run() throws RemoteException { 1269d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana // If the caller doesn't have permission then create and return the 1270d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana // "grant permission" intent instead of the "getAuthToken" intent. 1271d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (!permissionGranted) { 1272d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana mAuthenticator.getAuthTokenLabel(this, authTokenType); 1273d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } else { 1274d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana mAuthenticator.getAuthToken(this, account, authTokenType, loginOptions); 1275d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 127626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1277a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 127826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana public void onResult(Bundle result) { 127926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana if (result != null) { 1280f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana if (result.containsKey(AccountManager.KEY_AUTH_TOKEN_LABEL)) { 1281d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Intent intent = newGrantCredentialsPermissionIntent(account, callerUid, 1282d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana new AccountAuthenticatorResponse(this), 1283d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana authTokenType, 1284f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana result.getString(AccountManager.KEY_AUTH_TOKEN_LABEL)); 1285d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Bundle bundle = new Bundle(); 1286f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana bundle.putParcelable(AccountManager.KEY_INTENT, intent); 1287d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana onResult(bundle); 1288d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana return; 1289d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1290f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana String authToken = result.getString(AccountManager.KEY_AUTHTOKEN); 129126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana if (authToken != null) { 1292f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana String name = result.getString(AccountManager.KEY_ACCOUNT_NAME); 1293f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana String type = result.getString(AccountManager.KEY_ACCOUNT_TYPE); 129426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana if (TextUtils.isEmpty(type) || TextUtils.isEmpty(name)) { 1295f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana onError(AccountManager.ERROR_CODE_INVALID_RESPONSE, 129626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana "the type and name should not be empty"); 129726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana return; 129826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1299a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache if (!customTokens) { 130004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani saveAuthTokenToDatabase(mAccounts, new Account(name, type), 1301a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache authTokenType, authToken); 1302a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache } 1303a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1304603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1305f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana Intent intent = result.getParcelable(AccountManager.KEY_INTENT); 1306d606045070dcf6a011e49a7711d2f17d8f2de8c1Costin Manolache if (intent != null && notifyOnAuthFailure && !customTokens) { 130704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani doNotification(mAccounts, 1308f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana account, result.getString(AccountManager.KEY_AUTH_FAILED_MESSAGE), 13094120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn intent, accounts.userId); 131026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1311a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 131226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana super.onResult(result); 1313a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 131426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana }.bind(); 131526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 131626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 131726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1318603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1319603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 13204120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn private void createNoCredentialsPermissionNotification(Account account, Intent intent, 13214120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn int userId) { 1322d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana int uid = intent.getIntExtra( 1323d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana GrantCredentialsPermissionActivity.EXTRAS_REQUESTING_UID, -1); 1324d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana String authTokenType = intent.getStringExtra( 1325d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana GrantCredentialsPermissionActivity.EXTRAS_AUTH_TOKEN_TYPE); 1326d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana String authTokenLabel = intent.getStringExtra( 1327d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana GrantCredentialsPermissionActivity.EXTRAS_AUTH_TOKEN_LABEL); 1328d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 1329d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Notification n = new Notification(android.R.drawable.stat_sys_warning, null, 1330d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 0 /* when */); 1331ee452ee5359cdfa3c3fbf6783722d3aaa2ec5ca6Eric Fischer final String titleAndSubtitle = 1332ee452ee5359cdfa3c3fbf6783722d3aaa2ec5ca6Eric Fischer mContext.getString(R.string.permission_request_notification_with_subtitle, 1333ee452ee5359cdfa3c3fbf6783722d3aaa2ec5ca6Eric Fischer account.name); 1334ee452ee5359cdfa3c3fbf6783722d3aaa2ec5ca6Eric Fischer final int index = titleAndSubtitle.indexOf('\n'); 133585e7279d9cc1ee8e4dd1f993a9e61a9eb547ecbcCostin Manolache String title = titleAndSubtitle; 133685e7279d9cc1ee8e4dd1f993a9e61a9eb547ecbcCostin Manolache String subtitle = ""; 133785e7279d9cc1ee8e4dd1f993a9e61a9eb547ecbcCostin Manolache if (index > 0) { 133885e7279d9cc1ee8e4dd1f993a9e61a9eb547ecbcCostin Manolache title = titleAndSubtitle.substring(0, index); 13393df7d697ca86ee2081bcfba31bcbd3ae4f4bcdf8Jatin Lodhia subtitle = titleAndSubtitle.substring(index + 1); 134085e7279d9cc1ee8e4dd1f993a9e61a9eb547ecbcCostin Manolache } 134150cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn UserHandle user = new UserHandle(userId); 13424120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn n.setLatestEventInfo(mContext, title, subtitle, 13434120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn PendingIntent.getActivityAsUser(mContext, 0, intent, 134450cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn PendingIntent.FLAG_CANCEL_CURRENT, null, user)); 134550cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn installNotification(getCredentialPermissionNotificationId( 134650cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn account, authTokenType, uid), n, user); 1347d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1348d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 13495f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache private Intent newGrantCredentialsPermissionIntent(Account account, int uid, 13505f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache AccountAuthenticatorResponse response, String authTokenType, String authTokenLabel) { 1351d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 1352d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Intent intent = new Intent(mContext, GrantCredentialsPermissionActivity.class); 135346703b099516c383a6882815bcf9cd4df0ec538dBrian Carlstrom // See FLAG_ACTIVITY_NEW_TASK docs for limitations and benefits of the flag. 13549ec17366c17efd14c643ee88fa1132ab05197349Costin Manolache // Since it was set in Eclair+ we can't change it without breaking apps using 13559ec17366c17efd14c643ee88fa1132ab05197349Costin Manolache // the intent from a non-Activity context. 13569ec17366c17efd14c643ee88fa1132ab05197349Costin Manolache intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 1357d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana intent.addCategory( 1358d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana String.valueOf(getCredentialPermissionNotificationId(account, authTokenType, uid))); 13595f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache 1360d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana intent.putExtra(GrantCredentialsPermissionActivity.EXTRAS_ACCOUNT, account); 1361d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana intent.putExtra(GrantCredentialsPermissionActivity.EXTRAS_AUTH_TOKEN_TYPE, authTokenType); 1362d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana intent.putExtra(GrantCredentialsPermissionActivity.EXTRAS_RESPONSE, response); 1363d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana intent.putExtra(GrantCredentialsPermissionActivity.EXTRAS_REQUESTING_UID, uid); 13645f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache 1365d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana return intent; 1366d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1367d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 1368d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private Integer getCredentialPermissionNotificationId(Account account, String authTokenType, 1369d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana int uid) { 1370d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Integer id; 1371f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackborn UserAccounts accounts = getUserAccounts(UserHandle.getUserId(uid)); 137204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.credentialsPermissionNotificationIds) { 1373d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana final Pair<Pair<Account, String>, Integer> key = 1374d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana new Pair<Pair<Account, String>, Integer>( 1375d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana new Pair<Account, String>(account, authTokenType), uid); 137604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani id = accounts.credentialsPermissionNotificationIds.get(key); 1377d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (id == null) { 1378d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana id = mNotificationIds.incrementAndGet(); 137904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.credentialsPermissionNotificationIds.put(key, id); 1380d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1381d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1382d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana return id; 1383d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1384d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 138504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private Integer getSigninRequiredNotificationId(UserAccounts accounts, Account account) { 1386d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Integer id; 138704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.signinRequiredNotificationIds) { 138804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani id = accounts.signinRequiredNotificationIds.get(account); 1389d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (id == null) { 1390d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana id = mNotificationIds.incrementAndGet(); 139104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.signinRequiredNotificationIds.put(account, id); 1392d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1393d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1394d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana return id; 1395d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1396d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 13973326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana public void addAcount(final IAccountManagerResponse response, final String accountType, 13983326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana final String authTokenType, final String[] requiredFeatures, 1399b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache final boolean expectActivityLaunch, final Bundle optionsIn) { 140056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 140156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "addAccount: accountType " + accountType 140256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", response " + response 140356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", authTokenType " + authTokenType 140456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", requiredFeatures " + stringArrayToString(requiredFeatures) 140556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", expectActivityLaunch " + expectActivityLaunch 140656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 140756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 140856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 1409382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (response == null) throw new IllegalArgumentException("response is null"); 1410382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (accountType == null) throw new IllegalArgumentException("accountType is null"); 1411d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkManageAccountsPermission(); 1412b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache 141371e6c697e54a43d357cc25d87a446d140f17396aAmith Yamasani // Is user disallowed from modifying accounts? 141471e6c697e54a43d357cc25d87a446d140f17396aAmith Yamasani if (getUserManager().getUserRestrictions(Binder.getCallingUserHandle()) 141571e6c697e54a43d357cc25d87a446d140f17396aAmith Yamasani .getBoolean(UserManager.DISALLOW_MODIFY_ACCOUNTS, false)) { 1416df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani try { 1417df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani response.onError(AccountManager.ERROR_CODE_USER_RESTRICTED, 1418df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani "User is not allowed to add an account!"); 1419df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani } catch (RemoteException re) { 1420df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani } 1421df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani return; 1422df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani } 1423df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani 142404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 1425b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache final int pid = Binder.getCallingPid(); 1426b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache final int uid = Binder.getCallingUid(); 1427b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache final Bundle options = (optionsIn == null) ? new Bundle() : optionsIn; 1428b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache options.putInt(AccountManager.KEY_CALLER_UID, uid); 1429b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache options.putInt(AccountManager.KEY_CALLER_PID, pid); 1430b61e8fbabea2cc40ad65bf4f372a32d526cfc7acCostin Manolache 143126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 143226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 143304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani new Session(accounts, response, accountType, expectActivityLaunch, 14348570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana true /* stripAuthTokenFromResult */) { 143526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana public void run() throws RemoteException { 14363348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache mAuthenticator.addAccount(this, mAccountType, authTokenType, requiredFeatures, 14373326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana options); 143826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1439a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 144026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana protected String toDebugString(long now) { 144126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana return super.toDebugString(now) + ", addAccount" 14423326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + ", accountType " + accountType 14433326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + ", requiredFeatures " 14443326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + (requiredFeatures != null 14453326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana ? TextUtils.join(",", requiredFeatures) 14463326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana : null); 144726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 144826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana }.bind(); 144926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 145026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 145126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1452603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1453603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 14542c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani @Override 14552c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani public void confirmCredentialsAsUser(IAccountManagerResponse response, 14562c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani final Account account, final Bundle options, final boolean expectActivityLaunch, 14572c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani int userId) { 14582c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani // Only allow the system process to read accounts of other users 14592c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani if (userId != UserHandle.getCallingUserId() 14602c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani && Binder.getCallingUid() != android.os.Process.myUid()) { 14612c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani throw new SecurityException("User " + UserHandle.getCallingUserId() 14622c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani + " trying to confirm account credentials for " + userId); 14632c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani } 14642c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani 146556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 146656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "confirmCredentials: " + account 146756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", response " + response 146856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", expectActivityLaunch " + expectActivityLaunch 146956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 147056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 147156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 1472382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (response == null) throw new IllegalArgumentException("response is null"); 1473382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 1474d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkManageAccountsPermission(); 14752c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani UserAccounts accounts = getUserAccounts(userId); 147626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 147726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 147804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani new Session(accounts, response, account.type, expectActivityLaunch, 14798570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana true /* stripAuthTokenFromResult */) { 148026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana public void run() throws RemoteException { 1481f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana mAuthenticator.confirmCredentials(this, account, options); 148226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 148326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana protected String toDebugString(long now) { 148426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana return super.toDebugString(now) + ", confirmCredentials" 148526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana + ", " + account; 148626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 148726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana }.bind(); 148826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 148926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 149026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1491603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1492603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1493a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void updateCredentials(IAccountManagerResponse response, final Account account, 1494a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana final String authTokenType, final boolean expectActivityLaunch, 1495a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana final Bundle loginOptions) { 149656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 149756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "updateCredentials: " + account 149856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", response " + response 149956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", authTokenType " + authTokenType 150056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", expectActivityLaunch " + expectActivityLaunch 150156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 150256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 150356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 1504382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (response == null) throw new IllegalArgumentException("response is null"); 1505382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 1506382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null"); 1507d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkManageAccountsPermission(); 150804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 150926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 151026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 151104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani new Session(accounts, response, account.type, expectActivityLaunch, 15128570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana true /* stripAuthTokenFromResult */) { 151326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana public void run() throws RemoteException { 151426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana mAuthenticator.updateCredentials(this, account, authTokenType, loginOptions); 151526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 151626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana protected String toDebugString(long now) { 151726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana if (loginOptions != null) loginOptions.keySet(); 151826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana return super.toDebugString(now) + ", updateCredentials" 151926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana + ", " + account 152026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana + ", authTokenType " + authTokenType 152126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana + ", loginOptions " + loginOptions; 152226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 152326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana }.bind(); 152426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 152526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 152626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1527603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1528603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1529a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void editProperties(IAccountManagerResponse response, final String accountType, 1530a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana final boolean expectActivityLaunch) { 153156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 153256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "editProperties: accountType " + accountType 153356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", response " + response 153456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", expectActivityLaunch " + expectActivityLaunch 153556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 153656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 153756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 1538382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (response == null) throw new IllegalArgumentException("response is null"); 1539382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (accountType == null) throw new IllegalArgumentException("accountType is null"); 1540d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkManageAccountsPermission(); 154104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 154226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 154326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 154404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani new Session(accounts, response, accountType, expectActivityLaunch, 15458570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana true /* stripAuthTokenFromResult */) { 154626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana public void run() throws RemoteException { 154726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana mAuthenticator.editProperties(this, mAccountType); 154826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 154926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana protected String toDebugString(long now) { 155026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana return super.toDebugString(now) + ", editProperties" 155126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana + ", accountType " + accountType; 155226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 155326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana }.bind(); 155426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 155526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 155626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1557603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1558603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 15593326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana private class GetAccountsByTypeAndFeatureSession extends Session { 15603326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana private final String[] mFeatures; 15613326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana private volatile Account[] mAccountsOfType = null; 15623326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana private volatile ArrayList<Account> mAccountsWithFeatures = null; 15633326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana private volatile int mCurrentAccount = 0; 1564df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani private int mCallingUid; 15653326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 156604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani public GetAccountsByTypeAndFeatureSession(UserAccounts accounts, 1567df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani IAccountManagerResponse response, String type, String[] features, int callingUid) { 156804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani super(accounts, response, type, false /* expectActivityLaunch */, 15698570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana true /* stripAuthTokenFromResult */); 1570df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani mCallingUid = callingUid; 15713326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana mFeatures = features; 15723326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 15733326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 15743326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana public void run() throws RemoteException { 157504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (mAccounts.cacheLock) { 1576df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani mAccountsOfType = getAccountsFromCacheLocked(mAccounts, mAccountType, mCallingUid); 1577f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 15783326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana // check whether each account matches the requested features 15793326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana mAccountsWithFeatures = new ArrayList<Account>(mAccountsOfType.length); 15803326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana mCurrentAccount = 0; 15813326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 15823326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana checkAccount(); 15833326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 15843326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 15853326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana public void checkAccount() { 15863326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana if (mCurrentAccount >= mAccountsOfType.length) { 15873326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana sendResult(); 15883326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana return; 15893326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 15903326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 159129e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana final IAccountAuthenticator accountAuthenticator = mAuthenticator; 159229e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana if (accountAuthenticator == null) { 159329e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana // It is possible that the authenticator has died, which is indicated by 159429e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana // mAuthenticator being set to null. If this happens then just abort. 159529e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana // There is no need to send back a result or error in this case since 159629e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana // that already happened when mAuthenticator was cleared. 159729e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 159829e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana Log.v(TAG, "checkAccount: aborting session since we are no longer" 159929e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana + " connected to the authenticator, " + toDebugString()); 160029e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana } 160129e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana return; 160229e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana } 16033326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana try { 160429e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana accountAuthenticator.hasFeatures(this, mAccountsOfType[mCurrentAccount], mFeatures); 16053326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } catch (RemoteException e) { 1606f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana onError(AccountManager.ERROR_CODE_REMOTE_EXCEPTION, "remote exception"); 1607a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1608603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1609603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 16103326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana public void onResult(Bundle result) { 16113326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana mNumResults++; 16123326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana if (result == null) { 1613f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana onError(AccountManager.ERROR_CODE_INVALID_RESPONSE, "null bundle"); 16143326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana return; 16153326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 1616f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana if (result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT, false)) { 16173326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana mAccountsWithFeatures.add(mAccountsOfType[mCurrentAccount]); 16183326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 16193326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana mCurrentAccount++; 16203326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana checkAccount(); 1621a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 16223326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 16233326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana public void sendResult() { 16243326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana IAccountManagerResponse response = getResponseAndClose(); 16253326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana if (response != null) { 16263326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana try { 16273326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana Account[] accounts = new Account[mAccountsWithFeatures.size()]; 16283326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana for (int i = 0; i < accounts.length; i++) { 16293326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana accounts[i] = mAccountsWithFeatures.get(i); 16303326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 163156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 163256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, getClass().getSimpleName() + " calling onResult() on response " 163356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + response); 163456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 16353326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana Bundle result = new Bundle(); 1636f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana result.putParcelableArray(AccountManager.KEY_ACCOUNTS, accounts); 16373326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana response.onResult(result); 16383326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } catch (RemoteException e) { 16393326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana // if the caller is dead then there is no one to care about remote exceptions 16403326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 16413326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana Log.v(TAG, "failure while notifying response", e); 16423326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 16433326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 16443326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 16453326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 16463326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 16473326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 16483326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana protected String toDebugString(long now) { 16493326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana return super.toDebugString(now) + ", getAccountsByTypeAndFeatures" 16503326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + ", " + (mFeatures != null ? TextUtils.join(",", mFeatures) : null); 16513326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 16523326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 1653ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 165404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani /** 165504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani * Returns the accounts for a specific user 165604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani * @hide 165704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani */ 165804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani public Account[] getAccounts(int userId) { 165904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani checkReadAccountsPermission(); 166004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccounts(userId); 1661df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani int callingUid = Binder.getCallingUid(); 166204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani long identityToken = clearCallingIdentity(); 166304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani try { 166404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 1665df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani return getAccountsFromCacheLocked(accounts, null, callingUid); 166604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 166704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } finally { 166804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani restoreCallingIdentity(identityToken); 166904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 167004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 167104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani 1672f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani /** 16736ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey * Returns accounts for all running users. 16746ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey * 1675f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani * @hide 1676f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani */ 16776ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey public AccountAndUser[] getRunningAccounts() { 16786ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey final int[] runningUserIds; 16796ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey try { 16806ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey runningUserIds = ActivityManagerNative.getDefault().getRunningUserIds(); 16816ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey } catch (RemoteException e) { 16826ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey // Running in system_server; should never happen 16836ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey throw new RuntimeException(e); 16846ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey } 16856eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey return getAccounts(runningUserIds); 16866eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey } 16876eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey 16886eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey /** {@hide} */ 16896eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey public AccountAndUser[] getAllAccounts() { 16906eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey final List<UserInfo> users = getUserManager().getUsers(); 16916eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey final int[] userIds = new int[users.size()]; 16926eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey for (int i = 0; i < userIds.length; i++) { 16936eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey userIds[i] = users.get(i).id; 16946eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey } 16956eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey return getAccounts(userIds); 16966eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey } 16976ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey 16986eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey private AccountAndUser[] getAccounts(int[] userIds) { 16996ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey final ArrayList<AccountAndUser> runningAccounts = Lists.newArrayList(); 17006ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey synchronized (mUsers) { 17016eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey for (int userId : userIds) { 17026ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey UserAccounts userAccounts = getUserAccounts(userId); 1703f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani if (userAccounts == null) continue; 1704f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani synchronized (userAccounts.cacheLock) { 1705df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani Account[] accounts = getAccountsFromCacheLocked(userAccounts, null, 1706df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani Binder.getCallingUid()); 1707f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani for (int a = 0; a < accounts.length; a++) { 17086ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey runningAccounts.add(new AccountAndUser(accounts[a], userId)); 1709f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani } 1710f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani } 1711f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani } 1712f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani } 17136ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey 17146ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey AccountAndUser[] accountsArray = new AccountAndUser[runningAccounts.size()]; 17156ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey return runningAccounts.toArray(accountsArray); 1716f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani } 1717f29f2369cf4e1de090c985ed53d3f5e59535986aAmith Yamasani 17182c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani @Override 17192c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani public Account[] getAccountsAsUser(String type, int userId) { 1720df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani final int callingUid = Binder.getCallingUid(); 17212c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani // Only allow the system process to read accounts of other users 17222c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani if (userId != UserHandle.getCallingUserId() 1723df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani && callingUid != android.os.Process.myUid()) { 17242c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani throw new SecurityException("User " + UserHandle.getCallingUserId() 17252c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani + " trying to get account for " + userId); 17262c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani } 17272c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani 172856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 172956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "getAccounts: accountType " + type 173056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 173156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 173256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 1733ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana checkReadAccountsPermission(); 17342c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani UserAccounts accounts = getUserAccounts(userId); 1735ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana long identityToken = clearCallingIdentity(); 1736ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana try { 173704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 1738df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani return getAccountsFromCacheLocked(accounts, type, callingUid); 1739f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 1740ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } finally { 1741ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana restoreCallingIdentity(identityToken); 1742ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 1743ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 1744ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 17452c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani @Override 174667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani public boolean addSharedAccountAsUser(Account account, int userId) { 174767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani userId = handleIncomingUser(userId); 174867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani SQLiteDatabase db = getUserAccounts(userId).openHelper.getWritableDatabase(); 174967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani ContentValues values = new ContentValues(); 175067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani values.put(ACCOUNTS_NAME, account.name); 175167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani values.put(ACCOUNTS_TYPE, account.type); 175267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani db.delete(TABLE_SHARED_ACCOUNTS, ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?", 175367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani new String[] {account.name, account.type}); 175467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani long accountId = db.insert(TABLE_SHARED_ACCOUNTS, ACCOUNTS_NAME, values); 175567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani if (accountId < 0) { 175667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani Log.w(TAG, "insertAccountIntoDatabase: " + account 175767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani + ", skipping the DB insert failed"); 175867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani return false; 175967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 176067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani return true; 176167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 176267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani 176367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani @Override 176467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani public boolean removeSharedAccountAsUser(Account account, int userId) { 176567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani userId = handleIncomingUser(userId); 176667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani UserAccounts accounts = getUserAccounts(userId); 176767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani SQLiteDatabase db = accounts.openHelper.getWritableDatabase(); 176867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani int r = db.delete(TABLE_SHARED_ACCOUNTS, ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?", 176967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani new String[] {account.name, account.type}); 177067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani if (r > 0) { 177167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani removeAccountInternal(accounts, account); 177267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 177367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani return r > 0; 177467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 177567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani 177667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani @Override 177767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani public Account[] getSharedAccountsAsUser(int userId) { 177867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani userId = handleIncomingUser(userId); 177967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani UserAccounts accounts = getUserAccounts(userId); 178067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani ArrayList<Account> accountList = new ArrayList<Account>(); 178167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani Cursor cursor = null; 178267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani try { 178367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani cursor = accounts.openHelper.getReadableDatabase() 178467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani .query(TABLE_SHARED_ACCOUNTS, new String[]{ACCOUNTS_NAME, ACCOUNTS_TYPE}, 178567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani null, null, null, null, null); 178667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani if (cursor != null && cursor.moveToFirst()) { 178767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani int nameIndex = cursor.getColumnIndex(ACCOUNTS_NAME); 178867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani int typeIndex = cursor.getColumnIndex(ACCOUNTS_TYPE); 178967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani do { 179067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani accountList.add(new Account(cursor.getString(nameIndex), 179167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani cursor.getString(typeIndex))); 179267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } while (cursor.moveToNext()); 179367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 179467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } finally { 179567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani if (cursor != null) { 179667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani cursor.close(); 179767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 179867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 179967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani Account[] accountArray = new Account[accountList.size()]; 180067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani accountList.toArray(accountArray); 180167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani return accountArray; 180267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 180367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani 180467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani @Override 18052c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani public Account[] getAccounts(String type) { 18062c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani return getAccountsAsUser(type, UserHandle.getCallingUserId()); 18072c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani } 18082c7bc26a7447e6ac9eadcf328259aa3bb1be2949Amith Yamasani 1809ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana public void getAccountsByFeatures(IAccountManagerResponse response, 18103326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana String type, String[] features) { 181156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 181256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "getAccounts: accountType " + type 181356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", response " + response 181456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", features " + stringArrayToString(features) 181556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 181656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 181756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 1818382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (response == null) throw new IllegalArgumentException("response is null"); 1819382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (type == null) throw new IllegalArgumentException("accountType is null"); 1820d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkReadAccountsPermission(); 182104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts userAccounts = getUserAccountsForCaller(); 1822df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani int callingUid = Binder.getCallingUid(); 18233326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana long identityToken = clearCallingIdentity(); 18243326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana try { 1825ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana if (features == null || features.length == 0) { 1826f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana Account[] accounts; 182704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (userAccounts.cacheLock) { 1828df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani accounts = getAccountsFromCacheLocked(userAccounts, type, callingUid); 1829f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 1830d4a9d6c42bb412e27a8383aaacd051419d98a662Fred Quintana Bundle result = new Bundle(); 1831d4a9d6c42bb412e27a8383aaacd051419d98a662Fred Quintana result.putParcelableArray(AccountManager.KEY_ACCOUNTS, accounts); 1832d4a9d6c42bb412e27a8383aaacd051419d98a662Fred Quintana onResult(response, result); 1833ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana return; 1834ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 1835df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani new GetAccountsByTypeAndFeatureSession(userAccounts, response, type, features, 1836df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani callingUid).bind(); 18373326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } finally { 18383326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana restoreCallingIdentity(identityToken); 18393326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 18403326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 18413326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 1842f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana private long getAccountIdLocked(SQLiteDatabase db, Account account) { 1843603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana Cursor cursor = db.query(TABLE_ACCOUNTS, new String[]{ACCOUNTS_ID}, 1844ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana "name=? AND type=?", new String[]{account.name, account.type}, null, null, null); 1845603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana try { 1846603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana if (cursor.moveToNext()) { 1847603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana return cursor.getLong(0); 1848603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1849603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana return -1; 1850603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } finally { 1851603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana cursor.close(); 1852603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1853603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1854603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1855f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana private long getExtrasIdLocked(SQLiteDatabase db, long accountId, String key) { 1856603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana Cursor cursor = db.query(TABLE_EXTRAS, new String[]{EXTRAS_ID}, 1857603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana EXTRAS_ACCOUNTS_ID + "=" + accountId + " AND " + EXTRAS_KEY + "=?", 1858603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana new String[]{key}, null, null, null); 1859603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana try { 1860603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana if (cursor.moveToNext()) { 1861603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana return cursor.getLong(0); 1862603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1863603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana return -1; 1864603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } finally { 1865603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana cursor.close(); 1866603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1867603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1868603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1869a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana private abstract class Session extends IAccountAuthenticatorResponse.Stub 1870b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana implements IBinder.DeathRecipient, ServiceConnection { 1871603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana IAccountManagerResponse mResponse; 1872603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana final String mAccountType; 1873a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana final boolean mExpectActivityLaunch; 1874a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana final long mCreationTime; 1875a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 18763326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana public int mNumResults = 0; 1877a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana private int mNumRequestContinued = 0; 1878a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana private int mNumErrors = 0; 1879a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 1880603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana IAccountAuthenticator mAuthenticator = null; 1881603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 18828570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana private final boolean mStripAuthTokenFromResult; 188304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani protected final UserAccounts mAccounts; 18848570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana 188504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani public Session(UserAccounts accounts, IAccountManagerResponse response, String accountType, 18868570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana boolean expectActivityLaunch, boolean stripAuthTokenFromResult) { 1887603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana super(); 188867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani //if (response == null) throw new IllegalArgumentException("response is null"); 18893326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana if (accountType == null) throw new IllegalArgumentException("accountType is null"); 189004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani mAccounts = accounts; 18918570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana mStripAuthTokenFromResult = stripAuthTokenFromResult; 1892603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mResponse = response; 1893603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mAccountType = accountType; 1894a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana mExpectActivityLaunch = expectActivityLaunch; 1895a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana mCreationTime = SystemClock.elapsedRealtime(); 1896a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana synchronized (mSessions) { 1897a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana mSessions.put(toString(), this); 1898a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 189967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani if (response != null) { 190067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani try { 190167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani response.asBinder().linkToDeath(this, 0 /* flags */); 190267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } catch (RemoteException e) { 190367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani mResponse = null; 190467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani binderDied(); 190567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 1906a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1907603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1908603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1909a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana IAccountManagerResponse getResponseAndClose() { 1910603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana if (mResponse == null) { 1911603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana // this session has already been closed 1912603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana return null; 1913603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1914a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana IAccountManagerResponse response = mResponse; 1915a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana close(); // this clears mResponse so we need to save the response before this call 1916a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana return response; 1917a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1918a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 1919a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana private void close() { 1920a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana synchronized (mSessions) { 1921a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (mSessions.remove(toString()) == null) { 1922a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana // the session was already closed, so bail out now 1923a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana return; 1924a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1925a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1926a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (mResponse != null) { 1927a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana // stop listening for response deaths 1928a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana mResponse.asBinder().unlinkToDeath(this, 0 /* flags */); 1929a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 1930a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana // clear this so that we don't accidentally send any further results 1931a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana mResponse = null; 1932a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1933603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana cancelTimeout(); 1934603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana unbind(); 1935a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1936a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 1937a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void binderDied() { 1938603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mResponse = null; 1939a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana close(); 1940a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1941a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 1942a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana protected String toDebugString() { 1943a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana return toDebugString(SystemClock.elapsedRealtime()); 1944a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1945a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 1946a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana protected String toDebugString(long now) { 1947a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana return "Session: expectLaunch " + mExpectActivityLaunch 1948a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + ", connected " + (mAuthenticator != null) 1949a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + ", stats (" + mNumResults + "/" + mNumRequestContinued 1950a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + "/" + mNumErrors + ")" 1951a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + ", lifetime " + ((now - mCreationTime) / 1000.0); 1952603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1953603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1954603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana void bind() { 1955a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 1956a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana Log.v(TAG, "initiating bind to authenticator type " + mAccountType); 1957a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1958b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana if (!bindToAuthenticator(mAccountType)) { 1959a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana Log.d(TAG, "bind attempt failed for " + toDebugString()); 1960f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana onError(AccountManager.ERROR_CODE_REMOTE_EXCEPTION, "bind failure"); 1961603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1962603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1963603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1964603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private void unbind() { 1965603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana if (mAuthenticator != null) { 1966603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mAuthenticator = null; 1967b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana mContext.unbindService(this); 1968603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1969603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1970603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1971603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public void scheduleTimeout() { 1972603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mMessageHandler.sendMessageDelayed( 1973603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mMessageHandler.obtainMessage(MESSAGE_TIMED_OUT, this), TIMEOUT_DELAY_MS); 1974603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1975603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1976603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public void cancelTimeout() { 1977603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mMessageHandler.removeMessages(MESSAGE_TIMED_OUT, this); 1978603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1979603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1980b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana public void onServiceConnected(ComponentName name, IBinder service) { 1981603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mAuthenticator = IAccountAuthenticator.Stub.asInterface(service); 1982a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana try { 1983a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana run(); 1984a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } catch (RemoteException e) { 1985f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana onError(AccountManager.ERROR_CODE_REMOTE_EXCEPTION, 1986a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana "remote exception"); 1987a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1988603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1989603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1990b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana public void onServiceDisconnected(ComponentName name) { 1991a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana mAuthenticator = null; 1992a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana IAccountManagerResponse response = getResponseAndClose(); 1993603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana if (response != null) { 1994166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana try { 1995166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana response.onError(AccountManager.ERROR_CODE_REMOTE_EXCEPTION, 1996166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana "disconnected"); 1997166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana } catch (RemoteException e) { 1998166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 1999166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana Log.v(TAG, "Session.onServiceDisconnected: " 2000166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana + "caught RemoteException while responding", e); 2001166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana } 2002166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana } 2003603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2004603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2005603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 2006b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana public abstract void run() throws RemoteException; 2007b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana 2008603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public void onTimedOut() { 2009a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana IAccountManagerResponse response = getResponseAndClose(); 2010603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana if (response != null) { 2011166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana try { 2012166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana response.onError(AccountManager.ERROR_CODE_REMOTE_EXCEPTION, 2013166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana "timeout"); 2014166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana } catch (RemoteException e) { 2015166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 2016166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana Log.v(TAG, "Session.onTimedOut: caught RemoteException while responding", 2017166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana e); 2018166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana } 2019166466d483cc3d57e7d3d465fd92ce62409c8455Fred Quintana } 2020603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2021603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2022603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 2023a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void onResult(Bundle result) { 2024a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana mNumResults++; 2025f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana if (result != null && !TextUtils.isEmpty(result.getString(AccountManager.KEY_AUTHTOKEN))) { 2026f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana String accountName = result.getString(AccountManager.KEY_ACCOUNT_NAME); 2027f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana String accountType = result.getString(AccountManager.KEY_ACCOUNT_TYPE); 2028d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (!TextUtils.isEmpty(accountName) && !TextUtils.isEmpty(accountType)) { 2029d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Account account = new Account(accountName, accountType); 203050cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn cancelNotification(getSigninRequiredNotificationId(mAccounts, account), 203150cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn new UserHandle(mAccounts.userId)); 2032d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2033603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2034a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana IAccountManagerResponse response; 2035a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (mExpectActivityLaunch && result != null 2036f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana && result.containsKey(AccountManager.KEY_INTENT)) { 2037a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana response = mResponse; 2038a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } else { 2039a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana response = getResponseAndClose(); 2040603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2041603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana if (response != null) { 2042603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana try { 2043a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (result == null) { 204456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 204556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, getClass().getSimpleName() 204656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + " calling onError() on response " + response); 204756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 2048f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana response.onError(AccountManager.ERROR_CODE_INVALID_RESPONSE, 2049a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana "null bundle returned"); 2050a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } else { 20518570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana if (mStripAuthTokenFromResult) { 20528570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana result.remove(AccountManager.KEY_AUTHTOKEN); 20538570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana } 205456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 205556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, getClass().getSimpleName() 205656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + " calling onResult() on response " + response); 205756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 2058a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana response.onResult(result); 2059a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 2060603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } catch (RemoteException e) { 2061a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana // if the caller is dead then there is no one to care about remote exceptions 2062a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 2063a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana Log.v(TAG, "failure while notifying response", e); 2064a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 2065603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2066603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2067603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2068603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 2069a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void onRequestContinued() { 2070a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana mNumRequestContinued++; 2071603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2072603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 2073603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public void onError(int errorCode, String errorMessage) { 2074a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana mNumErrors++; 2075a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana IAccountManagerResponse response = getResponseAndClose(); 2076a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (response != null) { 2077a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 207856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, getClass().getSimpleName() 207956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + " calling onError() on response " + response); 2080a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 2081a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana try { 2082a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana response.onError(errorCode, errorMessage); 2083a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } catch (RemoteException e) { 2084a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 2085a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana Log.v(TAG, "Session.onError: caught RemoteException while responding", e); 2086a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 2087a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 2088a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } else { 2089a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 2090a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana Log.v(TAG, "Session.onError: already closed"); 2091a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 2092603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2093603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2094b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana 2095b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana /** 2096b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana * find the component name for the authenticator and initiate a bind 2097b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana * if no authenticator or the bind fails then return false, otherwise return true 2098b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana */ 2099b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana private boolean bindToAuthenticator(String authenticatorType) { 21006ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey final AccountAuthenticatorCache.ServiceInfo<AuthenticatorDescription> authenticatorInfo; 21016ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey authenticatorInfo = mAuthenticatorCache.getServiceInfo( 21026ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey AuthenticatorDescription.newKey(authenticatorType), mAccounts.userId); 2103b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana if (authenticatorInfo == null) { 2104b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 2105b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana Log.v(TAG, "there is no authenticator for " + authenticatorType 2106b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana + ", bailing out"); 2107b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana } 2108b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana return false; 2109b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana } 2110b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana 2111b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana Intent intent = new Intent(); 2112b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana intent.setAction(AccountManager.ACTION_AUTHENTICATOR_INTENT); 2113b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana intent.setComponent(authenticatorInfo.componentName); 2114b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 2115b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana Log.v(TAG, "performing bindService to " + authenticatorInfo.componentName); 2116b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana } 211727b89e6658a0d233a53f5d7ca20dc57fec82d955Amith Yamasani if (!mContext.bindServiceAsUser(intent, this, Context.BIND_AUTO_CREATE, 211827b89e6658a0d233a53f5d7ca20dc57fec82d955Amith Yamasani new UserHandle(mAccounts.userId))) { 2119b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 2120b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana Log.v(TAG, "bindService to " + authenticatorInfo.componentName + " failed"); 2121b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana } 2122b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana return false; 2123b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana } 2124b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana 2125b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana 2126b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana return true; 2127b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana } 2128603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2129603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 2130603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private class MessageHandler extends Handler { 2131603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana MessageHandler(Looper looper) { 2132603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana super(looper); 2133603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 21343348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache 2135603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public void handleMessage(Message msg) { 2136603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana switch (msg.what) { 2137603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana case MESSAGE_TIMED_OUT: 2138603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana Session session = (Session)msg.obj; 2139603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana session.onTimedOut(); 2140603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana break; 2141603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 2142603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana default: 2143603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana throw new IllegalStateException("unhandled message: " + msg.what); 2144603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2145603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2146603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2147603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 214804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private static String getDatabaseName(int userId) { 214904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani File systemDir = Environment.getSystemSecureDirectory(); 215061f57379ca2c5b6290c8da7548fa17128f7ab24fAmith Yamasani File databaseFile = new File(Environment.getUserSystemDirectory(userId), DATABASE_NAME); 215104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani if (userId == 0) { 2152a23bb38628ac1f5dc4ebe6847faedc424dd5fce1Amith Yamasani // Migrate old file, if it exists, to the new location. 2153a23bb38628ac1f5dc4ebe6847faedc424dd5fce1Amith Yamasani // Make sure the new file doesn't already exist. A dummy file could have been 2154a23bb38628ac1f5dc4ebe6847faedc424dd5fce1Amith Yamasani // accidentally created in the old location, causing the new one to become corrupted 2155a23bb38628ac1f5dc4ebe6847faedc424dd5fce1Amith Yamasani // as well. 215604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani File oldFile = new File(systemDir, DATABASE_NAME); 2157a23bb38628ac1f5dc4ebe6847faedc424dd5fce1Amith Yamasani if (oldFile.exists() && !databaseFile.exists()) { 2158c6b0f99bb31405902b40a96f6491a9adcaaac169Marc Blank // Check for use directory; create if it doesn't exist, else renameTo will fail 215961f57379ca2c5b6290c8da7548fa17128f7ab24fAmith Yamasani File userDir = Environment.getUserSystemDirectory(userId); 2160c6b0f99bb31405902b40a96f6491a9adcaaac169Marc Blank if (!userDir.exists()) { 2161c6b0f99bb31405902b40a96f6491a9adcaaac169Marc Blank if (!userDir.mkdirs()) { 2162c6b0f99bb31405902b40a96f6491a9adcaaac169Marc Blank throw new IllegalStateException("User dir cannot be created: " + userDir); 2163c6b0f99bb31405902b40a96f6491a9adcaaac169Marc Blank } 2164c6b0f99bb31405902b40a96f6491a9adcaaac169Marc Blank } 2165c6b0f99bb31405902b40a96f6491a9adcaaac169Marc Blank if (!oldFile.renameTo(databaseFile)) { 2166c6b0f99bb31405902b40a96f6491a9adcaaac169Marc Blank throw new IllegalStateException("User dir cannot be migrated: " + databaseFile); 2167c6b0f99bb31405902b40a96f6491a9adcaaac169Marc Blank } 216804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 2169a8529f68671a8a118751cb6ad577f44eaf076b96Oscar Montemayor } 217004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani return databaseFile.getPath(); 2171a8529f68671a8a118751cb6ad577f44eaf076b96Oscar Montemayor } 2172a8529f68671a8a118751cb6ad577f44eaf076b96Oscar Montemayor 217304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani static class DatabaseHelper extends SQLiteOpenHelper { 2174a8529f68671a8a118751cb6ad577f44eaf076b96Oscar Montemayor 217504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani public DatabaseHelper(Context context, int userId) { 217604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani super(context, AccountManagerService.getDatabaseName(userId), null, DATABASE_VERSION); 2177603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2178603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 2179f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana /** 2180f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana * This call needs to be made while the mCacheLock is held. The way to 2181f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana * ensure this is to get the lock any time a method is called ont the DatabaseHelper 2182f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana * @param db The database. 2183f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana */ 2184603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana @Override 2185603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public void onCreate(SQLiteDatabase db) { 2186603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana db.execSQL("CREATE TABLE " + TABLE_ACCOUNTS + " ( " 2187603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + ACCOUNTS_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " 2188603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + ACCOUNTS_NAME + " TEXT NOT NULL, " 2189603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + ACCOUNTS_TYPE + " TEXT NOT NULL, " 2190603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + ACCOUNTS_PASSWORD + " TEXT, " 2191603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + "UNIQUE(" + ACCOUNTS_NAME + "," + ACCOUNTS_TYPE + "))"); 2192603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 2193603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana db.execSQL("CREATE TABLE " + TABLE_AUTHTOKENS + " ( " 2194603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + AUTHTOKENS_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " 2195603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + AUTHTOKENS_ACCOUNTS_ID + " INTEGER NOT NULL, " 2196603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + AUTHTOKENS_TYPE + " TEXT NOT NULL, " 2197603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + AUTHTOKENS_AUTHTOKEN + " TEXT, " 2198603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + "UNIQUE (" + AUTHTOKENS_ACCOUNTS_ID + "," + AUTHTOKENS_TYPE + "))"); 2199603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 2200d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana createGrantsTable(db); 2201d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 2202603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana db.execSQL("CREATE TABLE " + TABLE_EXTRAS + " ( " 2203603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + EXTRAS_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " 2204603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + EXTRAS_ACCOUNTS_ID + " INTEGER, " 2205603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + EXTRAS_KEY + " TEXT NOT NULL, " 2206603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + EXTRAS_VALUE + " TEXT, " 2207603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + "UNIQUE(" + EXTRAS_ACCOUNTS_ID + "," + EXTRAS_KEY + "))"); 2208603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 2209603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana db.execSQL("CREATE TABLE " + TABLE_META + " ( " 2210603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + META_KEY + " TEXT PRIMARY KEY NOT NULL, " 2211603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + META_VALUE + " TEXT)"); 2212a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 221367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani createSharedAccountsTable(db); 221467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani 2215d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana createAccountsDeletionTrigger(db); 2216d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2217d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 221867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani private void createSharedAccountsTable(SQLiteDatabase db) { 221967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani db.execSQL("CREATE TABLE " + TABLE_SHARED_ACCOUNTS + " ( " 222067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani + ACCOUNTS_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " 222167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani + ACCOUNTS_NAME + " TEXT NOT NULL, " 222267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani + ACCOUNTS_TYPE + " TEXT NOT NULL, " 222367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani + "UNIQUE(" + ACCOUNTS_NAME + "," + ACCOUNTS_TYPE + "))"); 222467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 222567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani 2226d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private void createAccountsDeletionTrigger(SQLiteDatabase db) { 2227a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana db.execSQL("" 2228a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + " CREATE TRIGGER " + TABLE_ACCOUNTS + "Delete DELETE ON " + TABLE_ACCOUNTS 2229a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + " BEGIN" 2230a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + " DELETE FROM " + TABLE_AUTHTOKENS 2231a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + " WHERE " + AUTHTOKENS_ACCOUNTS_ID + "=OLD." + ACCOUNTS_ID + " ;" 2232a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + " DELETE FROM " + TABLE_EXTRAS 2233a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + " WHERE " + EXTRAS_ACCOUNTS_ID + "=OLD." + ACCOUNTS_ID + " ;" 2234d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + " DELETE FROM " + TABLE_GRANTS 2235d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + " WHERE " + GRANTS_ACCOUNTS_ID + "=OLD." + ACCOUNTS_ID + " ;" 2236a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + " END"); 2237603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2238603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 2239d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private void createGrantsTable(SQLiteDatabase db) { 2240d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana db.execSQL("CREATE TABLE " + TABLE_GRANTS + " ( " 2241d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + GRANTS_ACCOUNTS_ID + " INTEGER NOT NULL, " 2242d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + GRANTS_AUTH_TOKEN_TYPE + " STRING NOT NULL, " 2243d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + GRANTS_GRANTEE_UID + " INTEGER NOT NULL, " 2244d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + "UNIQUE (" + GRANTS_ACCOUNTS_ID + "," + GRANTS_AUTH_TOKEN_TYPE 2245d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + "," + GRANTS_GRANTEE_UID + "))"); 2246d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2247d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 2248603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana @Override 2249603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 2250a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana Log.e(TAG, "upgrade from version " + oldVersion + " to version " + newVersion); 2251603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 2252a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (oldVersion == 1) { 2253d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana // no longer need to do anything since the work is done 2254d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana // when upgrading from version 2 2255d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana oldVersion++; 2256d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2257d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 2258d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (oldVersion == 2) { 2259d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana createGrantsTable(db); 2260d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana db.execSQL("DROP TRIGGER " + TABLE_ACCOUNTS + "Delete"); 2261d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana createAccountsDeletionTrigger(db); 2262a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana oldVersion++; 2263a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 22643348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache 22653348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache if (oldVersion == 3) { 22663348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache db.execSQL("UPDATE " + TABLE_ACCOUNTS + " SET " + ACCOUNTS_TYPE + 22673348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache " = 'com.google' WHERE " + ACCOUNTS_TYPE + " == 'com.google.GAIA'"); 22683348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache oldVersion++; 22693348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache } 227067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani 227167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani if (oldVersion == 4) { 227267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani createSharedAccountsTable(db); 227367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani oldVersion++; 227467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 227567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani 227667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani if (oldVersion != newVersion) { 227767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani Log.e(TAG, "failed to upgrade version " + oldVersion + " to version " + newVersion); 227867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 2279603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2280603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 2281603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana @Override 2282603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public void onOpen(SQLiteDatabase db) { 2283603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "opened database " + DATABASE_NAME); 2284603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2285603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2286603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 2287603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public IBinder onBind(Intent intent) { 2288603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana return asBinder(); 2289603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 2290a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 22911cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks /** 22921cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks * Searches array of arguments for the specified string 22931cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks * @param args array of argument strings 22941cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks * @param value value to search for 22951cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks * @return true if the value is contained in the array 22961cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks */ 22971cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks private static boolean scanArgs(String[] args, String value) { 22981cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks if (args != null) { 22991cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks for (String arg : args) { 23001cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks if (value.equals(arg)) { 23011cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks return true; 23021cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks } 2303a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 2304a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 23051cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks return false; 23061cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks } 2307a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 23086eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey @Override 23091cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) { 23103abd75ba3a981850cac43a401d0014a836559cb0Kenny Root if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 23113abd75ba3a981850cac43a401d0014a836559cb0Kenny Root != PackageManager.PERMISSION_GRANTED) { 23123abd75ba3a981850cac43a401d0014a836559cb0Kenny Root fout.println("Permission Denial: can't dump AccountsManager from from pid=" 23133abd75ba3a981850cac43a401d0014a836559cb0Kenny Root + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 23143abd75ba3a981850cac43a401d0014a836559cb0Kenny Root + " without permission " + android.Manifest.permission.DUMP); 23153abd75ba3a981850cac43a401d0014a836559cb0Kenny Root return; 23163abd75ba3a981850cac43a401d0014a836559cb0Kenny Root } 231704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final boolean isCheckinRequest = scanArgs(args, "--checkin") || scanArgs(args, "-c"); 23186eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey final IndentingPrintWriter ipw = new IndentingPrintWriter(fout, " "); 23196eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey 23206eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey final List<UserInfo> users = getUserManager().getUsers(); 23216eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey for (UserInfo user : users) { 23226eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey ipw.println("User " + user + ":"); 23236eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey ipw.increaseIndent(); 23246eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey dumpUser(getUserAccounts(user.id), fd, ipw, args, isCheckinRequest); 23256eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey ipw.println(); 23266eb9620ff289105c3fc4a1be28a8eebb17d044e0Jeff Sharkey ipw.decreaseIndent(); 232704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 232804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani } 23291cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks 233004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private void dumpUser(UserAccounts userAccounts, FileDescriptor fd, PrintWriter fout, 233104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani String[] args, boolean isCheckinRequest) { 233204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (userAccounts.cacheLock) { 233304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = userAccounts.openHelper.getReadableDatabase(); 2334a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 2335f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (isCheckinRequest) { 2336f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana // This is a checkin request. *Only* upload the account types and the count of each. 2337f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana Cursor cursor = db.query(TABLE_ACCOUNTS, ACCOUNT_TYPE_COUNT_PROJECTION, 2338f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana null, null, ACCOUNTS_TYPE, null, null); 2339f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana try { 2340f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana while (cursor.moveToNext()) { 2341f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana // print type,count 2342f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana fout.println(cursor.getString(0) + "," + cursor.getString(1)); 2343f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 2344f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } finally { 2345f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (cursor != null) { 2346f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana cursor.close(); 2347f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 23481cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks } 2349f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } else { 2350df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani Account[] accounts = getAccountsFromCacheLocked(userAccounts, null /* type */, 2351df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani android.os.Process.myUid()); 2352f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana fout.println("Accounts: " + accounts.length); 2353f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana for (Account account : accounts) { 2354f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana fout.println(" " + account); 23551cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks } 2356307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana 2357f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana fout.println(); 2358f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana synchronized (mSessions) { 2359f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana final long now = SystemClock.elapsedRealtime(); 2360f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana fout.println("Active Sessions: " + mSessions.size()); 2361f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana for (Session session : mSessions.values()) { 2362f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana fout.println(" " + session.toDebugString(now)); 2363f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 23641cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks } 23651cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks 2366f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana fout.println(); 23676ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey mAuthenticatorCache.dump(fd, fout, args, userAccounts.userId); 2368f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 23691cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks } 2370a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 2371a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 237204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private void doNotification(UserAccounts accounts, Account account, CharSequence message, 23734120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn Intent intent, int userId) { 237426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 237526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 237626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 237726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana Log.v(TAG, "doNotification: " + message + " intent:" + intent); 237826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 2379a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 2380d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (intent.getComponent() != null && 2381d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana GrantCredentialsPermissionActivity.class.getName().equals( 2382d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana intent.getComponent().getClassName())) { 23834120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn createNoCredentialsPermissionNotification(account, intent, userId); 2384d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } else { 238504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final Integer notificationId = getSigninRequiredNotificationId(accounts, account); 238633f889ae270f888f8fdc084f5f1f3d443532a46aFred Quintana intent.addCategory(String.valueOf(notificationId)); 2387d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Notification n = new Notification(android.R.drawable.stat_sys_warning, null, 2388d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 0 /* when */); 238950cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn UserHandle user = new UserHandle(userId); 239033f889ae270f888f8fdc084f5f1f3d443532a46aFred Quintana final String notificationTitleFormat = 239133f889ae270f888f8fdc084f5f1f3d443532a46aFred Quintana mContext.getText(R.string.notification_title).toString(); 239233f889ae270f888f8fdc084f5f1f3d443532a46aFred Quintana n.setLatestEventInfo(mContext, 239333f889ae270f888f8fdc084f5f1f3d443532a46aFred Quintana String.format(notificationTitleFormat, account.name), 23944120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn message, PendingIntent.getActivityAsUser( 23954120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn mContext, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT, 239650cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn null, user)); 239750cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn installNotification(notificationId, n, user); 2398d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 239926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 240026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 240126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 2402a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 2403a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 240450cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn protected void installNotification(final int notificationId, final Notification n, 240550cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn UserHandle user) { 240656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana ((NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE)) 240750cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn .notifyAsUser(null, notificationId, n, user); 240856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 240956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 241050cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn protected void cancelNotification(int id, UserHandle user) { 241126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 241226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 241326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana ((NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE)) 241450cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn .cancelAsUser(null, id, user); 241526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 241626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 241726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 2418a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 2419d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 2420b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana /** Succeeds if any of the specified permissions are granted. */ 2421b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana private void checkBinderPermission(String... permissions) { 2422d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana final int uid = Binder.getCallingUid(); 2423b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana 2424b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana for (String perm : permissions) { 2425b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana if (mContext.checkCallingOrSelfPermission(perm) == PackageManager.PERMISSION_GRANTED) { 2426b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 242756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, " caller uid " + uid + " has " + perm); 2428b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana } 2429b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana return; 2430b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana } 2431d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2432b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana 2433b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana String msg = "caller uid " + uid + " lacks any of " + TextUtils.join(",", permissions); 243456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.w(TAG, " " + msg); 2435b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana throw new SecurityException(msg); 2436d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2437d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 243867df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani private int handleIncomingUser(int userId) { 243967df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani try { 244067df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani return ActivityManagerNative.getDefault().handleIncomingUser( 244167df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani Binder.getCallingPid(), Binder.getCallingUid(), userId, true, true, "", null); 244267df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } catch (RemoteException re) { 244367df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani // Shouldn't happen, local. 244467df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 244567df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani return userId; 244667df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani } 244767df64b3a48a8157d08a98fa90135d0ac0ee621cAmith Yamasani 24486ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey private boolean inSystemImage(int callingUid) { 24496ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey final int callingUserId = UserHandle.getUserId(callingUid); 24506ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey 24516ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey final PackageManager userPackageManager; 24526ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey try { 24536ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey userPackageManager = mContext.createPackageContextAsUser( 24546ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey "android", 0, new UserHandle(callingUserId)).getPackageManager(); 24556ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey } catch (NameNotFoundException e) { 24566ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey return false; 24576ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey } 24586ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey 24596ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey String[] packages = userPackageManager.getPackagesForUid(callingUid); 24607be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana for (String name : packages) { 24617be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana try { 24626ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey PackageInfo packageInfo = userPackageManager.getPackageInfo(name, 0 /* flags */); 246356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (packageInfo != null 246456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana && (packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 24657be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana return true; 24667be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana } 24677be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana } catch (PackageManager.NameNotFoundException e) { 24687be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana return false; 24697be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana } 24707be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana } 24717be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana return false; 24727be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana } 24737be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana 2474d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private boolean permissionIsGranted(Account account, String authTokenType, int callerUid) { 2475b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana final boolean inSystemImage = inSystemImage(callerUid); 247631957f1badbb900bbfe211317e1ea992d650a72dFred Quintana final boolean fromAuthenticator = account != null 247731957f1badbb900bbfe211317e1ea992d650a72dFred Quintana && hasAuthenticatorUid(account.type, callerUid); 247831957f1badbb900bbfe211317e1ea992d650a72dFred Quintana final boolean hasExplicitGrants = account != null 247904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani && hasExplicitlyGrantedPermission(account, authTokenType, callerUid); 2480d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 2481d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Log.v(TAG, "checkGrantsOrCallingUidAgainstAuthenticator: caller uid " 248256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + callerUid + ", " + account 2483d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + ": is authenticator? " + fromAuthenticator 2484d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + ", has explicit permission? " + hasExplicitGrants); 2485d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2486b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana return fromAuthenticator || hasExplicitGrants || inSystemImage; 2487d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2488d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 24891a23191bbde11505d6e0c25c04a60b41cb27fd31Fred Quintana private boolean hasAuthenticatorUid(String accountType, int callingUid) { 24906ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey final int callingUserId = UserHandle.getUserId(callingUid); 2491d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana for (RegisteredServicesCache.ServiceInfo<AuthenticatorDescription> serviceInfo : 24926ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey mAuthenticatorCache.getAllServices(callingUserId)) { 2493d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (serviceInfo.type.type.equals(accountType)) { 2494ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana return (serviceInfo.uid == callingUid) || 249556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana (mPackageManager.checkSignatures(serviceInfo.uid, callingUid) 2496ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana == PackageManager.SIGNATURE_MATCH); 2497d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2498d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2499d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana return false; 2500d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2501d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 250204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private boolean hasExplicitlyGrantedPermission(Account account, String authTokenType, 250304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani int callerUid) { 250404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani if (callerUid == android.os.Process.SYSTEM_UID) { 2505d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana return true; 2506d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 250704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani UserAccounts accounts = getUserAccountsForCaller(); 250804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 250904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getReadableDatabase(); 251004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani String[] args = { String.valueOf(callerUid), authTokenType, 2511f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana account.name, account.type}; 2512f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana final boolean permissionGranted = 2513f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana DatabaseUtils.longForQuery(db, COUNT_OF_MATCHING_GRANTS, args) != 0; 2514f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (!permissionGranted && ActivityManager.isRunningInTestHarness()) { 2515f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana // TODO: Skip this check when running automated tests. Replace this 2516f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana // with a more general solution. 2517f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana Log.d(TAG, "no credentials permission for usage of " + account + ", " 251804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani + authTokenType + " by uid " + callerUid 2519f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana + " but ignoring since device is in test harness."); 2520f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return true; 2521f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 2522f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return permissionGranted; 2523d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2524d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2525d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 2526d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private void checkCallingUidAgainstAuthenticator(Account account) { 2527d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana final int uid = Binder.getCallingUid(); 252831957f1badbb900bbfe211317e1ea992d650a72dFred Quintana if (account == null || !hasAuthenticatorUid(account.type, uid)) { 2529d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana String msg = "caller uid " + uid + " is different than the authenticator's uid"; 2530d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Log.w(TAG, msg); 2531d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana throw new SecurityException(msg); 2532d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2533d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 2534d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Log.v(TAG, "caller uid " + uid + " is the same as the authenticator's uid"); 2535d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2536d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2537d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 2538d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private void checkAuthenticateAccountsPermission(Account account) { 2539d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkBinderPermission(Manifest.permission.AUTHENTICATE_ACCOUNTS); 2540d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkCallingUidAgainstAuthenticator(account); 2541d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2542d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 2543d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private void checkReadAccountsPermission() { 2544d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkBinderPermission(Manifest.permission.GET_ACCOUNTS); 2545d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2546d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 2547d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private void checkManageAccountsPermission() { 2548d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkBinderPermission(Manifest.permission.MANAGE_ACCOUNTS); 2549d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2550d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 2551b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana private void checkManageAccountsOrUseCredentialsPermissions() { 2552b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana checkBinderPermission(Manifest.permission.MANAGE_ACCOUNTS, 2553b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana Manifest.permission.USE_CREDENTIALS); 2554b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana } 2555b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana 2556e4cf73437a18c1444055f88a1fcc0d146ec23ac5Amith Yamasani private boolean canUserModifyAccounts(int callingUid) { 2557e4cf73437a18c1444055f88a1fcc0d146ec23ac5Amith Yamasani if (callingUid != android.os.Process.myUid()) { 2558e4cf73437a18c1444055f88a1fcc0d146ec23ac5Amith Yamasani Bundle restrictions = getUserManager().getUserRestrictions( 2559e4cf73437a18c1444055f88a1fcc0d146ec23ac5Amith Yamasani new UserHandle(UserHandle.getUserId(callingUid))); 256071e6c697e54a43d357cc25d87a446d140f17396aAmith Yamasani if (restrictions.getBoolean(UserManager.DISALLOW_MODIFY_ACCOUNTS, false)) { 2561e4cf73437a18c1444055f88a1fcc0d146ec23ac5Amith Yamasani return false; 2562e4cf73437a18c1444055f88a1fcc0d146ec23ac5Amith Yamasani } 2563e4cf73437a18c1444055f88a1fcc0d146ec23ac5Amith Yamasani } 2564e4cf73437a18c1444055f88a1fcc0d146ec23ac5Amith Yamasani return true; 2565e4cf73437a18c1444055f88a1fcc0d146ec23ac5Amith Yamasani } 2566e4cf73437a18c1444055f88a1fcc0d146ec23ac5Amith Yamasani 2567d9640ec712806508877868d08aafaa2d715ff441Fred Quintana public void updateAppPermission(Account account, String authTokenType, int uid, boolean value) 2568d9640ec712806508877868d08aafaa2d715ff441Fred Quintana throws RemoteException { 2569d9640ec712806508877868d08aafaa2d715ff441Fred Quintana final int callingUid = getCallingUid(); 2570d9640ec712806508877868d08aafaa2d715ff441Fred Quintana 2571d9640ec712806508877868d08aafaa2d715ff441Fred Quintana if (callingUid != android.os.Process.SYSTEM_UID) { 2572d9640ec712806508877868d08aafaa2d715ff441Fred Quintana throw new SecurityException(); 2573d9640ec712806508877868d08aafaa2d715ff441Fred Quintana } 2574d9640ec712806508877868d08aafaa2d715ff441Fred Quintana 2575d9640ec712806508877868d08aafaa2d715ff441Fred Quintana if (value) { 2576d9640ec712806508877868d08aafaa2d715ff441Fred Quintana grantAppPermission(account, authTokenType, uid); 2577d9640ec712806508877868d08aafaa2d715ff441Fred Quintana } else { 2578d9640ec712806508877868d08aafaa2d715ff441Fred Quintana revokeAppPermission(account, authTokenType, uid); 2579d9640ec712806508877868d08aafaa2d715ff441Fred Quintana } 2580d9640ec712806508877868d08aafaa2d715ff441Fred Quintana } 2581d9640ec712806508877868d08aafaa2d715ff441Fred Quintana 2582d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana /** 2583d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * Allow callers with the given uid permission to get credentials for account/authTokenType. 2584d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * <p> 2585d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * Although this is public it can only be accessed via the AccountManagerService object 2586d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * which is in the system. This means we don't need to protect it with permissions. 2587d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * @hide 2588d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana */ 2589d9640ec712806508877868d08aafaa2d715ff441Fred Quintana private void grantAppPermission(Account account, String authTokenType, int uid) { 2590382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null || authTokenType == null) { 2591382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana Log.e(TAG, "grantAppPermission: called with invalid arguments", new Exception()); 259231957f1badbb900bbfe211317e1ea992d650a72dFred Quintana return; 259331957f1badbb900bbfe211317e1ea992d650a72dFred Quintana } 2594f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackborn UserAccounts accounts = getUserAccounts(UserHandle.getUserId(uid)); 259504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 259604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getWritableDatabase(); 2597f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.beginTransaction(); 2598f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana try { 2599f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana long accountId = getAccountIdLocked(db, account); 2600f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (accountId >= 0) { 2601f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana ContentValues values = new ContentValues(); 2602f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana values.put(GRANTS_ACCOUNTS_ID, accountId); 2603f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana values.put(GRANTS_AUTH_TOKEN_TYPE, authTokenType); 2604f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana values.put(GRANTS_GRANTEE_UID, uid); 2605f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.insert(TABLE_GRANTS, GRANTS_ACCOUNTS_ID, values); 2606f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.setTransactionSuccessful(); 2607f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 2608f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } finally { 2609f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.endTransaction(); 2610d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 261150cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn cancelNotification(getCredentialPermissionNotificationId(account, authTokenType, uid), 261250cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn new UserHandle(accounts.userId)); 2613d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2614d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2615d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 2616d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana /** 2617d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * Don't allow callers with the given uid permission to get credentials for 2618d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * account/authTokenType. 2619d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * <p> 2620d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * Although this is public it can only be accessed via the AccountManagerService object 2621d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * which is in the system. This means we don't need to protect it with permissions. 2622d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * @hide 2623d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana */ 2624d9640ec712806508877868d08aafaa2d715ff441Fred Quintana private void revokeAppPermission(Account account, String authTokenType, int uid) { 2625382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null || authTokenType == null) { 2626382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana Log.e(TAG, "revokeAppPermission: called with invalid arguments", new Exception()); 262731957f1badbb900bbfe211317e1ea992d650a72dFred Quintana return; 262831957f1badbb900bbfe211317e1ea992d650a72dFred Quintana } 2629f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackborn UserAccounts accounts = getUserAccounts(UserHandle.getUserId(uid)); 263004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 263104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getWritableDatabase(); 2632f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.beginTransaction(); 2633f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana try { 2634f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana long accountId = getAccountIdLocked(db, account); 2635f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (accountId >= 0) { 2636f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.delete(TABLE_GRANTS, 2637f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana GRANTS_ACCOUNTS_ID + "=? AND " + GRANTS_AUTH_TOKEN_TYPE + "=? AND " 2638f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana + GRANTS_GRANTEE_UID + "=?", 2639f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana new String[]{String.valueOf(accountId), authTokenType, 2640f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana String.valueOf(uid)}); 2641f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.setTransactionSuccessful(); 2642f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 2643f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } finally { 2644f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana db.endTransaction(); 2645d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 264650cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn cancelNotification(getCredentialPermissionNotificationId(account, authTokenType, uid), 264750cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn new UserHandle(accounts.userId)); 2648d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2649d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 265056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 265156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana static final private String stringArrayToString(String[] value) { 265256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana return value != null ? ("[" + TextUtils.join(",", value) + "]") : null; 265356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 265456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 265504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private void removeAccountFromCacheLocked(UserAccounts accounts, Account account) { 265604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final Account[] oldAccountsForType = accounts.accountCache.get(account.type); 2657f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (oldAccountsForType != null) { 2658f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana ArrayList<Account> newAccountsList = new ArrayList<Account>(); 2659f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana for (Account curAccount : oldAccountsForType) { 2660f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (!curAccount.equals(account)) { 2661f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana newAccountsList.add(curAccount); 266256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 266356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 2664f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (newAccountsList.isEmpty()) { 266504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.accountCache.remove(account.type); 2666f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } else { 2667f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana Account[] newAccountsForType = new Account[newAccountsList.size()]; 2668f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana newAccountsForType = newAccountsList.toArray(newAccountsForType); 266904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.accountCache.put(account.type, newAccountsForType); 2670f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 267156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 267204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.userDataCache.remove(account); 267304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.authTokenCache.remove(account); 267456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 267556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 267656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana /** 267756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana * This assumes that the caller has already checked that the account is not already present. 267856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana */ 267904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani private void insertAccountIntoCacheLocked(UserAccounts accounts, Account account) { 268004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani Account[] accountsForType = accounts.accountCache.get(account.type); 2681f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana int oldLength = (accountsForType != null) ? accountsForType.length : 0; 2682f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana Account[] newAccountsForType = new Account[oldLength + 1]; 2683f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (accountsForType != null) { 2684f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana System.arraycopy(accountsForType, 0, newAccountsForType, 0, oldLength); 2685f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 2686f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana newAccountsForType[oldLength] = account; 268704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.accountCache.put(account.type, newAccountsForType); 2688f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 2689f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana 2690df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani private Account[] filterSharedAccounts(UserAccounts userAccounts, Account[] unfiltered, 2691df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani int callingUid) { 2692df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani if (getUserManager() == null || userAccounts == null || userAccounts.userId < 0 2693df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani || callingUid == android.os.Process.myUid()) { 2694df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani return unfiltered; 2695df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani } 2696df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani if (mUserManager.getUserInfo(userAccounts.userId).isRestricted()) { 2697df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani String[] packages = mPackageManager.getPackagesForUid(callingUid); 2698df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani // If any of the packages includes a white listed package, return the full set, 2699df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani // otherwise return non-shared accounts only. 2700df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani // This might be a temporary way to specify a whitelist 2701df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani String whiteList = mContext.getResources().getString( 2702df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani com.android.internal.R.string.config_appsAuthorizedForSharedAccounts); 2703df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani for (String packageName : packages) { 2704df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani if (whiteList.contains(";" + packageName + ";")) { 2705df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani return unfiltered; 2706df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani } 2707df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani } 2708df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani ArrayList<Account> allowed = new ArrayList<Account>(); 2709df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani Account[] sharedAccounts = getSharedAccountsAsUser(userAccounts.userId); 2710df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani if (sharedAccounts == null || sharedAccounts.length == 0) return unfiltered; 2711df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani for (Account account : unfiltered) { 2712df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani boolean found = false; 2713df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani for (Account shared : sharedAccounts) { 2714df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani if (shared.equals(account)) { 2715df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani found = true; 2716df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani break; 2717df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani } 2718df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani } 2719df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani if (!found) { 2720df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani allowed.add(account); 2721df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani } 2722df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani } 2723df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani Account[] filtered = new Account[allowed.size()]; 2724df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani allowed.toArray(filtered); 2725df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani return filtered; 2726df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani } else { 2727df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani return unfiltered; 2728df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani } 2729df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani } 2730df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani 2731df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani protected Account[] getAccountsFromCacheLocked(UserAccounts userAccounts, String accountType, 2732df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani int callingUid) { 2733f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (accountType != null) { 273404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final Account[] accounts = userAccounts.accountCache.get(accountType); 2735f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (accounts == null) { 2736f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return EMPTY_ACCOUNT_ARRAY; 273756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } else { 2738df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani return filterSharedAccounts(userAccounts, Arrays.copyOf(accounts, accounts.length), 2739df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani callingUid); 2740f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 2741f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } else { 2742f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana int totalLength = 0; 274304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani for (Account[] accounts : userAccounts.accountCache.values()) { 2744f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana totalLength += accounts.length; 2745f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 2746f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (totalLength == 0) { 2747f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana return EMPTY_ACCOUNT_ARRAY; 2748f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 2749f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana Account[] accounts = new Account[totalLength]; 2750f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana totalLength = 0; 275104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani for (Account[] accountsOfType : userAccounts.accountCache.values()) { 2752f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana System.arraycopy(accountsOfType, 0, accounts, totalLength, 2753f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana accountsOfType.length); 2754f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana totalLength += accountsOfType.length; 275556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 2756df2e92a535e19c00edd37318d974dab992ccc2c1Amith Yamasani return filterSharedAccounts(userAccounts, accounts, callingUid); 275756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 275856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 275956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 276004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani protected void writeUserDataIntoCacheLocked(UserAccounts accounts, final SQLiteDatabase db, 276104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani Account account, String key, String value) { 276204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani HashMap<String, String> userDataForAccount = accounts.userDataCache.get(account); 2763f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (userDataForAccount == null) { 2764f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana userDataForAccount = readUserDataForAccountFromDatabaseLocked(db, account); 276504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.userDataCache.put(account, userDataForAccount); 2766f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 2767f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (value == null) { 2768f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana userDataForAccount.remove(key); 2769f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } else { 2770f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana userDataForAccount.put(key, value); 277156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 277256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 277356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 277404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani protected void writeAuthTokenIntoCacheLocked(UserAccounts accounts, final SQLiteDatabase db, 277504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani Account account, String key, String value) { 277604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani HashMap<String, String> authTokensForAccount = accounts.authTokenCache.get(account); 2777f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (authTokensForAccount == null) { 2778f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana authTokensForAccount = readAuthTokensForAccountFromDatabaseLocked(db, account); 277904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.authTokenCache.put(account, authTokensForAccount); 2780f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } 2781f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana if (value == null) { 2782f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana authTokensForAccount.remove(key); 2783f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana } else { 2784f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana authTokensForAccount.put(key, value); 278556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 278656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 278756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 278804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani protected String readAuthTokenInternal(UserAccounts accounts, Account account, 278904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani String authTokenType) { 279004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 279104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani HashMap<String, String> authTokensForAccount = accounts.authTokenCache.get(account); 279256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (authTokensForAccount == null) { 279356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana // need to populate the cache for this account 279404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getReadableDatabase(); 2795f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana authTokensForAccount = readAuthTokensForAccountFromDatabaseLocked(db, account); 279604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.authTokenCache.put(account, authTokensForAccount); 279756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 279856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana return authTokensForAccount.get(authTokenType); 279956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 280056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 280156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 280204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani protected String readUserDataInternal(UserAccounts accounts, Account account, String key) { 280304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani synchronized (accounts.cacheLock) { 280404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani HashMap<String, String> userDataForAccount = accounts.userDataCache.get(account); 280556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (userDataForAccount == null) { 280656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana // need to populate the cache for this account 280704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani final SQLiteDatabase db = accounts.openHelper.getReadableDatabase(); 2808f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana userDataForAccount = readUserDataForAccountFromDatabaseLocked(db, account); 280904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani accounts.userDataCache.put(account, userDataForAccount); 281056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 281156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana return userDataForAccount.get(key); 281256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 281356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 281456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 2815f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana protected HashMap<String, String> readUserDataForAccountFromDatabaseLocked( 2816f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana final SQLiteDatabase db, Account account) { 281756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana HashMap<String, String> userDataForAccount = new HashMap<String, String>(); 281856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Cursor cursor = db.query(TABLE_EXTRAS, 281956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana COLUMNS_EXTRAS_KEY_AND_VALUE, 282056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana SELECTION_USERDATA_BY_ACCOUNT, 282156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana new String[]{account.name, account.type}, 282256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana null, null, null); 282356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana try { 282456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana while (cursor.moveToNext()) { 282556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final String tmpkey = cursor.getString(0); 282656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final String value = cursor.getString(1); 282756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana userDataForAccount.put(tmpkey, value); 282856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 282956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } finally { 283056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana cursor.close(); 283156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 283256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana return userDataForAccount; 283356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 283456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 2835f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana protected HashMap<String, String> readAuthTokensForAccountFromDatabaseLocked( 2836f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana final SQLiteDatabase db, Account account) { 283756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana HashMap<String, String> authTokensForAccount = new HashMap<String, String>(); 283856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Cursor cursor = db.query(TABLE_AUTHTOKENS, 283956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana COLUMNS_AUTHTOKENS_TYPE_AND_AUTHTOKEN, 284056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana SELECTION_AUTHTOKENS_BY_ACCOUNT, 284156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana new String[]{account.name, account.type}, 284256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana null, null, null); 284356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana try { 284456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana while (cursor.moveToNext()) { 284556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final String type = cursor.getString(0); 284656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final String authToken = cursor.getString(1); 284756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana authTokensForAccount.put(type, authToken); 284856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 284956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } finally { 285056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana cursor.close(); 285156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 285256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana return authTokensForAccount; 285356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 2854603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana} 2855