AccountManagerService.java revision 9ec17366c17efd14c643ee88fa1132ab05197349
1603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana/* 2603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * Copyright (C) 2009 The Android Open Source Project 3603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * 4603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * Licensed under the Apache License, Version 2.0 (the "License"); 5603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * you may not use this file except in compliance with the License. 6603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * You may obtain a copy of the License at 7603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * 8603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * http://www.apache.org/licenses/LICENSE-2.0 9603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * 10603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * Unless required by applicable law or agreed to in writing, software 11603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * distributed under the License is distributed on an "AS IS" BASIS, 12603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * See the License for the specific language governing permissions and 14603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * limitations under the License. 15603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana */ 16603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 17603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintanapackage android.accounts; 18603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintanaimport com.android.internal.R; 2056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintanaimport com.android.internal.telephony.ITelephony; 2156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintanaimport com.android.internal.telephony.TelephonyIntents; 2256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 23885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongkerimport android.Manifest; 243b4fcbc9f13bab6a2e9e5c37cc5e18fec7341c04Brett Chabotimport android.app.ActivityManager; 25885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongkerimport android.app.Notification; 26885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongkerimport android.app.NotificationManager; 27885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongkerimport android.app.PendingIntent; 28a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.content.BroadcastReceiver; 29885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongkerimport android.content.ComponentName; 30a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.content.ContentValues; 31a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.content.Context; 32a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.content.Intent; 33a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.content.IntentFilter; 34b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintanaimport android.content.ServiceConnection; 35885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongkerimport android.content.pm.ApplicationInfo; 36885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongkerimport android.content.pm.PackageInfo; 37d4a1d2e14297a3387fdb5761090961e714370492Fred Quintanaimport android.content.pm.PackageManager; 38d4a1d2e14297a3387fdb5761090961e714370492Fred Quintanaimport android.content.pm.RegisteredServicesCache; 393ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintanaimport android.content.pm.RegisteredServicesCacheListener; 40603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintanaimport android.database.Cursor; 41603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintanaimport android.database.DatabaseUtils; 42a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.database.sqlite.SQLiteDatabase; 43a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.database.sqlite.SQLiteOpenHelper; 44885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongkerimport android.os.Binder; 45a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.os.Bundle; 46a8529f68671a8a118751cb6ad577f44eaf076b96Oscar Montemayorimport android.os.Environment; 47a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.os.Handler; 48a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.os.HandlerThread; 49a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.os.IBinder; 50a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.os.Looper; 51a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.os.Message; 52a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.os.RemoteException; 53885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongkerimport android.os.ServiceManager; 54a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.os.SystemClock; 55d4a1d2e14297a3387fdb5761090961e714370492Fred Quintanaimport android.os.SystemProperties; 56603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintanaimport android.telephony.TelephonyManager; 57a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.text.TextUtils; 58a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.util.Log; 59d4a1d2e14297a3387fdb5761090961e714370492Fred Quintanaimport android.util.Pair; 60603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 61a8529f68671a8a118751cb6ad577f44eaf076b96Oscar Montemayorimport java.io.File; 62a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport java.io.FileDescriptor; 63a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport java.io.PrintWriter; 64a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport java.util.ArrayList; 6556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintanaimport java.util.Arrays; 66a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport java.util.Collection; 67d4a1d2e14297a3387fdb5761090961e714370492Fred Quintanaimport java.util.HashMap; 6856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintanaimport java.util.LinkedHashMap; 69d4a1d2e14297a3387fdb5761090961e714370492Fred Quintanaimport java.util.concurrent.atomic.AtomicInteger; 70d4a1d2e14297a3387fdb5761090961e714370492Fred Quintanaimport java.util.concurrent.atomic.AtomicReference; 71603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 72603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana/** 73603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * A system service that provides account, password, and authtoken management for all 74603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * accounts on the device. Some of these calls are implemented with the help of the corresponding 75603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * {@link IAccountAuthenticator} services. This service is not accessed by users directly, 76603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * instead one uses an instance of {@link AccountManager}, which can be accessed as follows: 77603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * AccountManager accountManager = 78603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * (AccountManager)context.getSystemService(Context.ACCOUNT_SERVICE) 793326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana * @hide 80603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana */ 813ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintanapublic class AccountManagerService 823ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintana extends IAccountManager.Stub 835ebbb4a6b3e16f711735ae0615b9a9ea64faad38Fred Quintana implements RegisteredServicesCacheListener<AuthenticatorDescription> { 843348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache private static final String GOOGLE_ACCOUNT_TYPE = "com.google"; 8550c05f38b3728b7430dd4bb8d98565d9c5e56798Jim Miller 86603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String TAG = "AccountManagerService"; 87603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 88603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final int TIMEOUT_DELAY_MS = 1000 * 60; 89603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String DATABASE_NAME = "accounts.db"; 903348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache private static final int DATABASE_VERSION = 4; 91603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 92603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private final Context mContext; 93603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 9456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana private final PackageManager mPackageManager; 9556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 96603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private HandlerThread mMessageThread; 97603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private final MessageHandler mMessageHandler; 98603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 99603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana // Messages that can be sent on mHandler 100603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final int MESSAGE_TIMED_OUT = 3; 101603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 10256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana private final IAccountAuthenticatorCache mAuthenticatorCache; 103603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private final DatabaseHelper mOpenHelper; 104603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private final SimWatcher mSimWatcher; 105603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 106603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String TABLE_ACCOUNTS = "accounts"; 107603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String ACCOUNTS_ID = "_id"; 108603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String ACCOUNTS_NAME = "name"; 109603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String ACCOUNTS_TYPE = "type"; 1101cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks private static final String ACCOUNTS_TYPE_COUNT = "count(type)"; 111603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String ACCOUNTS_PASSWORD = "password"; 112603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 113603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String TABLE_AUTHTOKENS = "authtokens"; 114603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String AUTHTOKENS_ID = "_id"; 115603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String AUTHTOKENS_ACCOUNTS_ID = "accounts_id"; 116603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String AUTHTOKENS_TYPE = "type"; 117603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String AUTHTOKENS_AUTHTOKEN = "authtoken"; 118603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 119d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private static final String TABLE_GRANTS = "grants"; 120d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private static final String GRANTS_ACCOUNTS_ID = "accounts_id"; 121d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private static final String GRANTS_AUTH_TOKEN_TYPE = "auth_token_type"; 122d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private static final String GRANTS_GRANTEE_UID = "uid"; 123d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 124603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String TABLE_EXTRAS = "extras"; 125603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String EXTRAS_ID = "_id"; 126603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String EXTRAS_ACCOUNTS_ID = "accounts_id"; 127603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String EXTRAS_KEY = "key"; 128603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String EXTRAS_VALUE = "value"; 129603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 130603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String TABLE_META = "meta"; 131603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String META_KEY = "key"; 132603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String META_VALUE = "value"; 133603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1341cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks private static final String[] ACCOUNT_TYPE_COUNT_PROJECTION = 1351cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks new String[] { ACCOUNTS_TYPE, ACCOUNTS_TYPE_COUNT}; 1367be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana private static final Intent ACCOUNTS_CHANGED_INTENT; 137a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 138d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private static final String COUNT_OF_MATCHING_GRANTS = "" 139d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + "SELECT COUNT(*) FROM " + TABLE_GRANTS + ", " + TABLE_ACCOUNTS 140d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + " WHERE " + GRANTS_ACCOUNTS_ID + "=" + ACCOUNTS_ID 141d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + " AND " + GRANTS_GRANTEE_UID + "=?" 142d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + " AND " + GRANTS_AUTH_TOKEN_TYPE + "=?" 143d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + " AND " + ACCOUNTS_NAME + "=?" 144d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + " AND " + ACCOUNTS_TYPE + "=?"; 145d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 14656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana private static final String SELECTION_AUTHTOKENS_BY_ACCOUNT = 14756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana AUTHTOKENS_ACCOUNTS_ID + "=(select _id FROM accounts WHERE name=? AND type=?)"; 14856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana private static final String[] COLUMNS_AUTHTOKENS_TYPE_AND_AUTHTOKEN = {AUTHTOKENS_TYPE, 14956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana AUTHTOKENS_AUTHTOKEN}; 15056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 15156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana private static final String SELECTION_USERDATA_BY_ACCOUNT = 15256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana EXTRAS_ACCOUNTS_ID + "=(select _id FROM accounts WHERE name=? AND type=?)"; 15356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana private static final String[] COLUMNS_EXTRAS_KEY_AND_VALUE = {EXTRAS_KEY, EXTRAS_VALUE}; 15456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 155a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana private final LinkedHashMap<String, Session> mSessions = new LinkedHashMap<String, Session>(); 156d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private final AtomicInteger mNotificationIds = new AtomicInteger(1); 157d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 158d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private final HashMap<Pair<Pair<Account, String>, Integer>, Integer> 159d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana mCredentialsPermissionNotificationIds = 160d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana new HashMap<Pair<Pair<Account, String>, Integer>, Integer>(); 161d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private final HashMap<Account, Integer> mSigninRequiredNotificationIds = 162d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana new HashMap<Account, Integer>(); 163d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private static AtomicReference<AccountManagerService> sThis = 164d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana new AtomicReference<AccountManagerService>(); 165d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 16631957f1badbb900bbfe211317e1ea992d650a72dFred Quintana private static final Account[] EMPTY_ACCOUNT_ARRAY = new Account[]{}; 1677be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana 1687be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana static { 169f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana ACCOUNTS_CHANGED_INTENT = new Intent(AccountManager.LOGIN_ACCOUNTS_CHANGED_ACTION); 1707be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana ACCOUNTS_CHANGED_INTENT.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 1717be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana } 1727be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana 17356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana private final Object mCacheLock = new Object(); 17456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana /** protected by the {@link #mCacheLock} */ 17556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana private final HashMap<String, Account[]> mAccountCache = new HashMap<String, Account[]>(); 17656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana /** protected by the {@link #mCacheLock} */ 17756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana private HashMap<Account, HashMap<String, String>> mUserDataCache = 17856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana new HashMap<Account, HashMap<String, String>>(); 17956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana /** protected by the {@link #mCacheLock} */ 18056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana private HashMap<Account, HashMap<String, String>> mAuthTokenCache = 18156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana new HashMap<Account, HashMap<String, String>>(); 18256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 183d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana /** 184d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * This should only be called by system code. One should only call this after the service 185d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * has started. 186d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * @return a reference to the AccountManagerService instance 187d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * @hide 188d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana */ 189d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana public static AccountManagerService getSingleton() { 190d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana return sThis.get(); 191d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 192603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 19356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana public AccountManagerService(Context context) { 19456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana this(context, context.getPackageManager(), new AccountAuthenticatorCache(context)); 195603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 196603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 19756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana public AccountManagerService(Context context, PackageManager packageManager, 19856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana IAccountAuthenticatorCache authenticatorCache) { 199603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mContext = context; 20056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana mPackageManager = packageManager; 201603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 202603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mOpenHelper = new DatabaseHelper(mContext); 203603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 204603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mMessageThread = new HandlerThread("AccountManagerService"); 205603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mMessageThread.start(); 206603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mMessageHandler = new MessageHandler(mMessageThread.getLooper()); 207603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 20856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana mAuthenticatorCache = authenticatorCache; 2095ebbb4a6b3e16f711735ae0615b9a9ea64faad38Fred Quintana mAuthenticatorCache.setListener(this, null /* Handler */); 210603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 211885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker mSimWatcher = new SimWatcher(mContext); 212d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana sThis.set(this); 213afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana 21456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana validateAccountsAndPopulateCache(); 215afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana } 216afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana 21756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana private void validateAccountsAndPopulateCache() { 218afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana boolean accountDeleted = false; 219afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana SQLiteDatabase db = mOpenHelper.getWritableDatabase(); 220afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana Cursor cursor = db.query(TABLE_ACCOUNTS, 221afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana new String[]{ACCOUNTS_ID, ACCOUNTS_TYPE, ACCOUNTS_NAME}, 222afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana null, null, null, null, null); 223afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana try { 22456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana synchronized (mCacheLock) { 22556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana mAccountCache.clear(); 22656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final HashMap<String, ArrayList<String>> accountNamesByType = 22756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana new HashMap<String, ArrayList<String>>(); 22856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana while (cursor.moveToNext()) { 22956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final long accountId = cursor.getLong(0); 23056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final String accountType = cursor.getString(1); 23156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final String accountName = cursor.getString(2); 23256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (mAuthenticatorCache.getServiceInfo( 23356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana AuthenticatorDescription.newKey(accountType)) == null) { 23456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.d(TAG, "deleting account " + accountName + " because type " 23556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + accountType + " no longer has a registered authenticator"); 23656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana db.delete(TABLE_ACCOUNTS, ACCOUNTS_ID + "=" + accountId, null); 23756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana accountDeleted = true; 23856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final Account account = new Account(accountName, accountType); 23956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana mUserDataCache.remove(account); 24056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana mAuthTokenCache.remove(account); 24156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } else { 24256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana ArrayList<String> accountNames = accountNamesByType.get(accountType); 24356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (accountNames == null) { 24456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana accountNames = new ArrayList<String>(); 24556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana accountNamesByType.put(accountType, accountNames); 24656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 24756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana accountNames.add(accountName); 24856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 24956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 25056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana for (HashMap.Entry<String, ArrayList<String>> cur : accountNamesByType.entrySet()) { 25156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final String accountType = cur.getKey(); 25256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final ArrayList<String> accountNames = cur.getValue(); 25356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final Account[] accountsForType = new Account[accountNames.size()]; 25456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana int i = 0; 25556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana for (String accountName : accountNames) { 25656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana accountsForType[i] = new Account(accountName, accountType); 25756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana ++i; 25856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 25956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana mAccountCache.put(accountType, accountsForType); 260afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana } 261afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana } 262afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana } finally { 263afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana cursor.close(); 264afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana if (accountDeleted) { 265afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana sendAccountsChangedBroadcast(); 266afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana } 267afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana } 2683ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintana } 2693ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintana 2705ebbb4a6b3e16f711735ae0615b9a9ea64faad38Fred Quintana public void onServiceChanged(AuthenticatorDescription desc, boolean removed) { 27156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana validateAccountsAndPopulateCache(); 272603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 273603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 274a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public String getPassword(Account account) { 27556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 27656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "getPassword: " + account 27756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 27856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 27956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 280382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 281d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkAuthenticateAccountsPermission(account); 282d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 28326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 284603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana try { 285ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana return readPasswordFromDatabase(account); 286603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } finally { 28726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 288603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 289603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 290603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 291ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana private String readPasswordFromDatabase(Account account) { 29231957f1badbb900bbfe211317e1ea992d650a72dFred Quintana if (account == null) { 29331957f1badbb900bbfe211317e1ea992d650a72dFred Quintana return null; 29431957f1badbb900bbfe211317e1ea992d650a72dFred Quintana } 29531957f1badbb900bbfe211317e1ea992d650a72dFred Quintana 296ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana SQLiteDatabase db = mOpenHelper.getReadableDatabase(); 297ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana Cursor cursor = db.query(TABLE_ACCOUNTS, new String[]{ACCOUNTS_PASSWORD}, 298ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?", 299ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana new String[]{account.name, account.type}, null, null, null); 300ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana try { 301ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana if (cursor.moveToNext()) { 302ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana return cursor.getString(0); 303ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 304ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana return null; 305ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } finally { 306ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana cursor.close(); 307ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 308ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 309ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 310a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public String getUserData(Account account, String key) { 31156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 31256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "getUserData: " + account 31356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", key " + key 31456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 31556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 31656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 317382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 318382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (key == null) throw new IllegalArgumentException("key is null"); 319d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkAuthenticateAccountsPermission(account); 32026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 321603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana try { 32256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana return readUserDataFromCache(account, key); 323ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } finally { 324ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana restoreCallingIdentity(identityToken); 325ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 326ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 327ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 3289788976b1465ce982b5ae7c741345edd0ecd9322Fred Quintana public AuthenticatorDescription[] getAuthenticatorTypes() { 32956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 33056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "getAuthenticatorTypes: " 33156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + "caller's uid " + Binder.getCallingUid() 33256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 33356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 33426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 33526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 3369788976b1465ce982b5ae7c741345edd0ecd9322Fred Quintana Collection<AccountAuthenticatorCache.ServiceInfo<AuthenticatorDescription>> 3379788976b1465ce982b5ae7c741345edd0ecd9322Fred Quintana authenticatorCollection = mAuthenticatorCache.getAllServices(); 3389788976b1465ce982b5ae7c741345edd0ecd9322Fred Quintana AuthenticatorDescription[] types = 3399788976b1465ce982b5ae7c741345edd0ecd9322Fred Quintana new AuthenticatorDescription[authenticatorCollection.size()]; 34026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana int i = 0; 3419788976b1465ce982b5ae7c741345edd0ecd9322Fred Quintana for (AccountAuthenticatorCache.ServiceInfo<AuthenticatorDescription> authenticator 342718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana : authenticatorCollection) { 343718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana types[i] = authenticator.type; 34426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana i++; 34526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 34626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana return types; 34726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 34826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 349a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 350a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 351a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 352a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public boolean addAccount(Account account, String password, Bundle extras) { 35356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 35456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "addAccount: " + account 35556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 35656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 35756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 358382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 359d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkAuthenticateAccountsPermission(account); 360d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 361603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana // fails if the account already exists 36226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 363603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana try { 364ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana return insertAccountIntoDatabase(account, password, extras); 365ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } finally { 366ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana restoreCallingIdentity(identityToken); 367ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 368ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 369ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 370ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana private boolean insertAccountIntoDatabase(Account account, String password, Bundle extras) { 371ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana SQLiteDatabase db = mOpenHelper.getWritableDatabase(); 372743dfad2a51e016ddb741c104317637089187753Fred Quintana if (account == null) { 373743dfad2a51e016ddb741c104317637089187753Fred Quintana return false; 374743dfad2a51e016ddb741c104317637089187753Fred Quintana } 375ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana db.beginTransaction(); 376ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana try { 377ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana long numMatches = DatabaseUtils.longForQuery(db, 378ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana "select count(*) from " + TABLE_ACCOUNTS 379ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana + " WHERE " + ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?", 380ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana new String[]{account.name, account.type}); 381ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana if (numMatches > 0) { 38256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.w(TAG, "insertAccountIntoDatabase: " + account 38356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", skipping since the account already exists"); 384ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana return false; 385ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 386ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana ContentValues values = new ContentValues(); 387ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana values.put(ACCOUNTS_NAME, account.name); 388ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana values.put(ACCOUNTS_TYPE, account.type); 389ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana values.put(ACCOUNTS_PASSWORD, password); 390ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana long accountId = db.insert(TABLE_ACCOUNTS, ACCOUNTS_NAME, values); 391ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana if (accountId < 0) { 39256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.w(TAG, "insertAccountIntoDatabase: " + account 39356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", skipping the DB insert failed"); 394ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana return false; 395ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 396ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana if (extras != null) { 397ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana for (String key : extras.keySet()) { 398ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana final String value = extras.getString(key); 399ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana if (insertExtra(db, accountId, key, value) < 0) { 40056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.w(TAG, "insertAccountIntoDatabase: " + account 40156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", skipping since insertExtra failed for key " + key); 402ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana return false; 403603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 404603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 405603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 406ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana db.setTransactionSuccessful(); 40756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana insertAccountIntoCache(account); 408603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } finally { 409ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana db.endTransaction(); 410603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 411afd2f549bb850828ad4961ccdae1bd5e8505baa4Fred Quintana sendAccountsChangedBroadcast(); 412743dfad2a51e016ddb741c104317637089187753Fred Quintana return true; 413603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 414603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 415603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private long insertExtra(SQLiteDatabase db, long accountId, String key, String value) { 416603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana ContentValues values = new ContentValues(); 417603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana values.put(EXTRAS_KEY, key); 418603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana values.put(EXTRAS_ACCOUNTS_ID, accountId); 419603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana values.put(EXTRAS_VALUE, value); 420603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana return db.insert(TABLE_EXTRAS, EXTRAS_KEY, values); 421603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 422603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 4233084a6f80180506ce26fe4773d9a19f004b7f625Fred Quintana public void hasFeatures(IAccountManagerResponse response, 424bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana Account account, String[] features) { 42556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 42656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "hasFeatures: " + account 42756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", response " + response 42856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", features " + stringArrayToString(features) 42956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 43056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 43156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 432382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (response == null) throw new IllegalArgumentException("response is null"); 433382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 434382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (features == null) throw new IllegalArgumentException("features is null"); 435bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana checkReadAccountsPermission(); 436bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana long identityToken = clearCallingIdentity(); 437bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana try { 438bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana new TestFeaturesSession(response, account, features).bind(); 439bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } finally { 440bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana restoreCallingIdentity(identityToken); 441bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 442bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 443bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana 444bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana private class TestFeaturesSession extends Session { 445bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana private final String[] mFeatures; 446bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana private final Account mAccount; 447bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana 448bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana public TestFeaturesSession(IAccountManagerResponse response, 449bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana Account account, String[] features) { 4508570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana super(response, account.type, false /* expectActivityLaunch */, 4518570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana true /* stripAuthTokenFromResult */); 452bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana mFeatures = features; 453bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana mAccount = account; 454bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 455bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana 456bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana public void run() throws RemoteException { 457bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana try { 458bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana mAuthenticator.hasFeatures(this, mAccount, mFeatures); 459bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } catch (RemoteException e) { 460bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana onError(AccountManager.ERROR_CODE_REMOTE_EXCEPTION, "remote exception"); 461bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 462bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 463bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana 464bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana public void onResult(Bundle result) { 465bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana IAccountManagerResponse response = getResponseAndClose(); 466bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana if (response != null) { 467bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana try { 468bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana if (result == null) { 469bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana onError(AccountManager.ERROR_CODE_INVALID_RESPONSE, "null bundle"); 470bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana return; 471bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 47256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 47356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, getClass().getSimpleName() + " calling onResult() on response " 47456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + response); 47556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 476bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana final Bundle newResult = new Bundle(); 477bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana newResult.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, 478bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT, false)); 479bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana response.onResult(newResult); 480bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } catch (RemoteException e) { 481bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana // if the caller is dead then there is no one to care about remote exceptions 482bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 483bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana Log.v(TAG, "failure while notifying response", e); 484bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 485bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 486bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 487bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 488bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana 489bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana protected String toDebugString(long now) { 4903084a6f80180506ce26fe4773d9a19f004b7f625Fred Quintana return super.toDebugString(now) + ", hasFeatures" 491bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana + ", " + mAccount 492bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana + ", " + (mFeatures != null ? TextUtils.join(",", mFeatures) : null); 493bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 494bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 495307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana 496ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana public void removeAccount(IAccountManagerResponse response, Account account) { 49756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 49856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "removeAccount: " + account 49956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", response " + response 50056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 50156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 50256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 503382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (response == null) throw new IllegalArgumentException("response is null"); 504382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 505d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkManageAccountsPermission(); 50626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 507ec0c4f4183630a64c2b2cc8f961dc7e11cc628caCostin Manolache 508ec0c4f4183630a64c2b2cc8f961dc7e11cc628caCostin Manolache cancelNotification(getSigninRequiredNotificationId(account)); 509ec0c4f4183630a64c2b2cc8f961dc7e11cc628caCostin Manolache synchronized(mCredentialsPermissionNotificationIds) { 510ec0c4f4183630a64c2b2cc8f961dc7e11cc628caCostin Manolache for (Pair<Pair<Account, String>, Integer> pair: 511ec0c4f4183630a64c2b2cc8f961dc7e11cc628caCostin Manolache mCredentialsPermissionNotificationIds.keySet()) { 512ec0c4f4183630a64c2b2cc8f961dc7e11cc628caCostin Manolache if (account.equals(pair.first.first)) { 513ec0c4f4183630a64c2b2cc8f961dc7e11cc628caCostin Manolache int id = mCredentialsPermissionNotificationIds.get(pair); 514ec0c4f4183630a64c2b2cc8f961dc7e11cc628caCostin Manolache cancelNotification(id); 515ec0c4f4183630a64c2b2cc8f961dc7e11cc628caCostin Manolache } 516ec0c4f4183630a64c2b2cc8f961dc7e11cc628caCostin Manolache } 517ec0c4f4183630a64c2b2cc8f961dc7e11cc628caCostin Manolache } 518ec0c4f4183630a64c2b2cc8f961dc7e11cc628caCostin Manolache 51926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 520ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana new RemoveAccountSession(response, account).bind(); 52126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 52226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 523a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 524603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 525603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 526ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana private class RemoveAccountSession extends Session { 527ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana final Account mAccount; 528ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana public RemoveAccountSession(IAccountManagerResponse response, Account account) { 5298570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana super(response, account.type, false /* expectActivityLaunch */, 5308570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana true /* stripAuthTokenFromResult */); 531ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana mAccount = account; 532ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 533ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 534ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana protected String toDebugString(long now) { 535ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana return super.toDebugString(now) + ", removeAccount" 536ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana + ", account " + mAccount; 537ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 538ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 539ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana public void run() throws RemoteException { 540ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana mAuthenticator.getAccountRemovalAllowed(this, mAccount); 541ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 542ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 543ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana public void onResult(Bundle result) { 544f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana if (result != null && result.containsKey(AccountManager.KEY_BOOLEAN_RESULT) 545f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana && !result.containsKey(AccountManager.KEY_INTENT)) { 546f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana final boolean removalAllowed = result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT); 547ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana if (removalAllowed) { 548ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana removeAccount(mAccount); 549ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 550ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana IAccountManagerResponse response = getResponseAndClose(); 551ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana if (response != null) { 55256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 55356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, getClass().getSimpleName() + " calling onResult() on response " 55456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + response); 55556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 556ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana Bundle result2 = new Bundle(); 557f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana result2.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, removalAllowed); 558ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana try { 559ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana response.onResult(result2); 560ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } catch (RemoteException e) { 561ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana // ignore 562ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 563ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 564ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 565ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana super.onResult(result); 566ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 567ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 568ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 56956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana protected void removeAccount(Account account) { 570ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana final SQLiteDatabase db = mOpenHelper.getWritableDatabase(); 571ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana db.delete(TABLE_ACCOUNTS, ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?", 572ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana new String[]{account.name, account.type}); 57356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana removeAccountFromCache(account); 574ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana sendAccountsChangedBroadcast(); 575ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 576ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 577a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void invalidateAuthToken(String accountType, String authToken) { 57856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 57956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "invalidateAuthToken: accountType " + accountType 58056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 58156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 58256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 583382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (accountType == null) throw new IllegalArgumentException("accountType is null"); 584382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (authToken == null) throw new IllegalArgumentException("authToken is null"); 585b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana checkManageAccountsOrUseCredentialsPermissions(); 58626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 587603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana try { 58826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana SQLiteDatabase db = mOpenHelper.getWritableDatabase(); 58926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana db.beginTransaction(); 59026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 59126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana invalidateAuthToken(db, accountType, authToken); 59226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana db.setTransactionSuccessful(); 59326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 59426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana db.endTransaction(); 59526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 596603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } finally { 59726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 598603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 599603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 600603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 601603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private void invalidateAuthToken(SQLiteDatabase db, String accountType, String authToken) { 602ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana if (authToken == null || accountType == null) { 603ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana return; 604ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 6053326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana Cursor cursor = db.rawQuery( 6063326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana "SELECT " + TABLE_AUTHTOKENS + "." + AUTHTOKENS_ID 6073326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + ", " + TABLE_ACCOUNTS + "." + ACCOUNTS_NAME 6083326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + ", " + TABLE_AUTHTOKENS + "." + AUTHTOKENS_TYPE 6093326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + " FROM " + TABLE_ACCOUNTS 6103326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + " JOIN " + TABLE_AUTHTOKENS 6113326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + " ON " + TABLE_ACCOUNTS + "." + ACCOUNTS_ID 6123326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + " = " + AUTHTOKENS_ACCOUNTS_ID 6133326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + " WHERE " + AUTHTOKENS_AUTHTOKEN + " = ? AND " 6143326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + TABLE_ACCOUNTS + "." + ACCOUNTS_TYPE + " = ?", 6153326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana new String[]{authToken, accountType}); 6163326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana try { 6173326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana while (cursor.moveToNext()) { 6183326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana long authTokenId = cursor.getLong(0); 6193326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana String accountName = cursor.getString(1); 6203326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana String authTokenType = cursor.getString(2); 6213326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana db.delete(TABLE_AUTHTOKENS, AUTHTOKENS_ID + "=" + authTokenId, null); 62256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana writeAuthTokenIntoCache(new Account(accountName, accountType), authTokenType, null); 623603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 6243326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } finally { 6253326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana cursor.close(); 626603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 627603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 628603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 629603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private boolean saveAuthTokenToDatabase(Account account, String type, String authToken) { 63031957f1badbb900bbfe211317e1ea992d650a72dFred Quintana if (account == null || type == null) { 63131957f1badbb900bbfe211317e1ea992d650a72dFred Quintana return false; 63231957f1badbb900bbfe211317e1ea992d650a72dFred Quintana } 6336dfd1382fe43592b9602fc6553e820c64067c759Fred Quintana cancelNotification(getSigninRequiredNotificationId(account)); 634603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana SQLiteDatabase db = mOpenHelper.getWritableDatabase(); 635603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana db.beginTransaction(); 636603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana try { 6373326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana long accountId = getAccountId(db, account); 6383326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana if (accountId < 0) { 6393326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana return false; 6403326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 6413326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana db.delete(TABLE_AUTHTOKENS, 6423326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana AUTHTOKENS_ACCOUNTS_ID + "=" + accountId + " AND " + AUTHTOKENS_TYPE + "=?", 6433326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana new String[]{type}); 6443326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana ContentValues values = new ContentValues(); 6453326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana values.put(AUTHTOKENS_ACCOUNTS_ID, accountId); 6463326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana values.put(AUTHTOKENS_TYPE, type); 6473326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana values.put(AUTHTOKENS_AUTHTOKEN, authToken); 6483326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana if (db.insert(TABLE_AUTHTOKENS, AUTHTOKENS_AUTHTOKEN, values) >= 0) { 649603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana db.setTransactionSuccessful(); 65056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana writeAuthTokenIntoCache(account, type, authToken); 651603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana return true; 652603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 653603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana return false; 654603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } finally { 655603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana db.endTransaction(); 656603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 657603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 658603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 659a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public String peekAuthToken(Account account, String authTokenType) { 66056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 66156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "peekAuthToken: " + account 66256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", authTokenType " + authTokenType 66356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 66456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 66556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 666382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 667382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null"); 668d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkAuthenticateAccountsPermission(account); 66926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 67026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 67156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana return readAuthTokenFromCache(account, authTokenType); 67226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 67326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 674603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 675603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 676603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 677a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void setAuthToken(Account account, String authTokenType, String authToken) { 67856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 67956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "setAuthToken: " + account 68056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", authTokenType " + authTokenType 68156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 68256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 68356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 684382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 685382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null"); 686d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkAuthenticateAccountsPermission(account); 68726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 68826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 6896dfd1382fe43592b9602fc6553e820c64067c759Fred Quintana saveAuthTokenToDatabase(account, authTokenType, authToken); 69026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 69126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 69226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 693603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 694603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 695a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void setPassword(Account account, String password) { 69656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 69756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "setAuthToken: " + account 69856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 69956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 70056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 701382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 702d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkAuthenticateAccountsPermission(account); 70326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 70426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 7053ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintana setPasswordInDB(account, password); 70626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 70726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 70826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 709603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 710603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 7113ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintana private void setPasswordInDB(Account account, String password) { 71231957f1badbb900bbfe211317e1ea992d650a72dFred Quintana if (account == null) { 71331957f1badbb900bbfe211317e1ea992d650a72dFred Quintana return; 71431957f1badbb900bbfe211317e1ea992d650a72dFred Quintana } 715d4a9d6c42bb412e27a8383aaacd051419d98a662Fred Quintana SQLiteDatabase db = mOpenHelper.getWritableDatabase(); 716d4a9d6c42bb412e27a8383aaacd051419d98a662Fred Quintana db.beginTransaction(); 717d4a9d6c42bb412e27a8383aaacd051419d98a662Fred Quintana try { 718d4a9d6c42bb412e27a8383aaacd051419d98a662Fred Quintana final ContentValues values = new ContentValues(); 719d4a9d6c42bb412e27a8383aaacd051419d98a662Fred Quintana values.put(ACCOUNTS_PASSWORD, password); 720d4a9d6c42bb412e27a8383aaacd051419d98a662Fred Quintana final long accountId = getAccountId(db, account); 721d4a9d6c42bb412e27a8383aaacd051419d98a662Fred Quintana if (accountId >= 0) { 722d4a9d6c42bb412e27a8383aaacd051419d98a662Fred Quintana final String[] argsAccountId = {String.valueOf(accountId)}; 723d4a9d6c42bb412e27a8383aaacd051419d98a662Fred Quintana db.update(TABLE_ACCOUNTS, values, ACCOUNTS_ID + "=?", argsAccountId); 724d4a9d6c42bb412e27a8383aaacd051419d98a662Fred Quintana db.delete(TABLE_AUTHTOKENS, AUTHTOKENS_ACCOUNTS_ID + "=?", argsAccountId); 725d4a9d6c42bb412e27a8383aaacd051419d98a662Fred Quintana db.setTransactionSuccessful(); 726d4a9d6c42bb412e27a8383aaacd051419d98a662Fred Quintana } 727d4a9d6c42bb412e27a8383aaacd051419d98a662Fred Quintana } finally { 728d4a9d6c42bb412e27a8383aaacd051419d98a662Fred Quintana db.endTransaction(); 729d4a9d6c42bb412e27a8383aaacd051419d98a662Fred Quintana } 7303ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintana sendAccountsChangedBroadcast(); 7313ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintana } 7323ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintana 7333326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana private void sendAccountsChangedBroadcast() { 73456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.i(TAG, "the accounts changed, sending broadcast of " 73556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ACCOUNTS_CHANGED_INTENT.getAction()); 7363326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana mContext.sendBroadcast(ACCOUNTS_CHANGED_INTENT); 7373326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 7383326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 739a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void clearPassword(Account account) { 74056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 74156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "clearPassword: " + account 74256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 74356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 74456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 745382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 746d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkManageAccountsPermission(); 74726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 74826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 7493ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintana setPasswordInDB(account, null); 75026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 75126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 75226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 753603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 754603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 755a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void setUserData(Account account, String key, String value) { 75656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 75756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "setUserData: " + account 75856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", key " + key 75956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 76056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 76156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 762382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (key == null) throw new IllegalArgumentException("key is null"); 763382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 764d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkAuthenticateAccountsPermission(account); 76526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 766603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana try { 767ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana writeUserdataIntoDatabase(account, key, value); 768ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } finally { 769ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana restoreCallingIdentity(identityToken); 770ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 771ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 772ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 773ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana private void writeUserdataIntoDatabase(Account account, String key, String value) { 77431957f1badbb900bbfe211317e1ea992d650a72dFred Quintana if (account == null || key == null) { 77531957f1badbb900bbfe211317e1ea992d650a72dFred Quintana return; 77631957f1badbb900bbfe211317e1ea992d650a72dFred Quintana } 777ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana SQLiteDatabase db = mOpenHelper.getWritableDatabase(); 778ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana db.beginTransaction(); 779ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana try { 780ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana long accountId = getAccountId(db, account); 781ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana if (accountId < 0) { 782ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana return; 783ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 784ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana long extrasId = getExtrasId(db, accountId, key); 785ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana if (extrasId < 0 ) { 786ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana extrasId = insertExtra(db, accountId, key, value); 787ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana if (extrasId < 0) { 788603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana return; 789603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 790ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } else { 791ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana ContentValues values = new ContentValues(); 792ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana values.put(EXTRAS_VALUE, value); 793ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana if (1 != db.update(TABLE_EXTRAS, values, EXTRAS_ID + "=" + extrasId, null)) { 794ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana return; 79526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 796ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 797603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 798ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana db.setTransactionSuccessful(); 79956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana writeUserDataIntoCache(account, key, value); 800603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } finally { 801ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana db.endTransaction(); 802603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 803603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 804603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 805d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private void onResult(IAccountManagerResponse response, Bundle result) { 80656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (result == null) { 80756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.e(TAG, "the result is unexpectedly null", new Exception()); 80856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 80956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 81056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, getClass().getSimpleName() + " calling onResult() on response " 81156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + response); 81256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 813d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana try { 814d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana response.onResult(result); 815d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } catch (RemoteException e) { 816d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana // if the caller is dead then there is no one to care about remote 817d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana // exceptions 818d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 819d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Log.v(TAG, "failure while notifying response", e); 820d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 821d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 822d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 823d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 8245f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache void getAuthTokenLabel(final IAccountManagerResponse response, 8255f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache final Account account, final String authTokenType) { 8265f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache if (account == null) throw new IllegalArgumentException("account is null"); 8275f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null"); 8285f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache 8295f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache checkBinderPermission(Manifest.permission.USE_CREDENTIALS); 8305f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache 8315f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache long identityToken = clearCallingIdentity(); 8325f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache try { 8335f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache new Session(response, account.type, false, 8345f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache false /* stripAuthTokenFromResult */) { 8355f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache protected String toDebugString(long now) { 8365f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache return super.toDebugString(now) + ", getAuthTokenLabel" 8375f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache + ", " + account 8385f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache + ", authTokenType " + authTokenType; 8395f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache } 8405f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache 8415f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache public void run() throws RemoteException { 8425f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache mAuthenticator.getAuthTokenLabel(this, authTokenType); 8435f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache } 8445f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache 8455f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache public void onResult(Bundle result) { 8465f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache if (result != null) { 8475f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache String label = result.getString(AccountManager.KEY_AUTH_TOKEN_LABEL); 8485f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache Bundle bundle = new Bundle(); 8495f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache bundle.putString(AccountManager.KEY_AUTH_TOKEN_LABEL, label); 8505f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache super.onResult(bundle); 8515f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache return; 8525f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache } else { 8535f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache super.onResult(result); 8545f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache } 8555f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache } 8565f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache }.bind(); 8575f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache } finally { 8585f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache restoreCallingIdentity(identityToken); 8595f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache } 8605f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache } 8615f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache 862a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void getAuthToken(IAccountManagerResponse response, final Account account, 863a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana final String authTokenType, final boolean notifyOnAuthFailure, 864c6684f9e9790e92960504e9b32f20f27003d9f37Costin Manolache final boolean expectActivityLaunch, Bundle loginOptionsIn) { 86556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 86656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "getAuthToken: " + account 86756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", response " + response 86856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", authTokenType " + authTokenType 86956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", notifyOnAuthFailure " + notifyOnAuthFailure 87056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", expectActivityLaunch " + expectActivityLaunch 87156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 87256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 87356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 874382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (response == null) throw new IllegalArgumentException("response is null"); 875382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 876382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null"); 877d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkBinderPermission(Manifest.permission.USE_CREDENTIALS); 878d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana final int callerUid = Binder.getCallingUid(); 879a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache final int callerPid = Binder.getCallingPid(); 880a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache 881a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache AccountAuthenticatorCache.ServiceInfo<AuthenticatorDescription> authenticatorInfo = 882a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache mAuthenticatorCache.getServiceInfo( 883a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache AuthenticatorDescription.newKey(account.type)); 884a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache final boolean customTokens = 885a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache authenticatorInfo != null && authenticatorInfo.type.customTokens; 886a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache 887a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache // skip the check if customTokens 888a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache final boolean permissionGranted = customTokens || 889a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache permissionIsGranted(account, authTokenType, callerUid); 890a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache 891c6684f9e9790e92960504e9b32f20f27003d9f37Costin Manolache final Bundle loginOptions = (loginOptionsIn == null) ? new Bundle() : 892c6684f9e9790e92960504e9b32f20f27003d9f37Costin Manolache loginOptionsIn; 893a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache if (customTokens) { 894a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache // let authenticator know the identity of the caller 895a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache loginOptions.putInt(AccountManager.KEY_CALLER_UID, callerUid); 896a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache loginOptions.putInt(AccountManager.KEY_CALLER_PID, callerPid); 897a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache } 898d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 89926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 90026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 901d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana // if the caller has permission, do the peek. otherwise go the more expensive 902d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana // route of starting a Session 903a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache if (!customTokens && permissionGranted) { 90456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana String authToken = readAuthTokenFromCache(account, authTokenType); 905d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (authToken != null) { 90626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana Bundle result = new Bundle(); 907f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana result.putString(AccountManager.KEY_AUTHTOKEN, authToken); 908f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name); 909f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana result.putString(AccountManager.KEY_ACCOUNT_TYPE, account.type); 910d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana onResult(response, result); 911d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana return; 912a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 913a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 914603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 9158570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana new Session(response, account.type, expectActivityLaunch, 9168570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana false /* stripAuthTokenFromResult */) { 91726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana protected String toDebugString(long now) { 91826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana if (loginOptions != null) loginOptions.keySet(); 91926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana return super.toDebugString(now) + ", getAuthToken" 92026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana + ", " + account 92126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana + ", authTokenType " + authTokenType 92226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana + ", loginOptions " + loginOptions 92326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana + ", notifyOnAuthFailure " + notifyOnAuthFailure; 92426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 925a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 92626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana public void run() throws RemoteException { 927d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana // If the caller doesn't have permission then create and return the 928d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana // "grant permission" intent instead of the "getAuthToken" intent. 929d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (!permissionGranted) { 930d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana mAuthenticator.getAuthTokenLabel(this, authTokenType); 931d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } else { 932d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana mAuthenticator.getAuthToken(this, account, authTokenType, loginOptions); 933d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 93426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 935a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 93626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana public void onResult(Bundle result) { 93726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana if (result != null) { 938f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana if (result.containsKey(AccountManager.KEY_AUTH_TOKEN_LABEL)) { 939d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Intent intent = newGrantCredentialsPermissionIntent(account, callerUid, 940d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana new AccountAuthenticatorResponse(this), 941d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana authTokenType, 942f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana result.getString(AccountManager.KEY_AUTH_TOKEN_LABEL)); 943d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Bundle bundle = new Bundle(); 944f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana bundle.putParcelable(AccountManager.KEY_INTENT, intent); 945d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana onResult(bundle); 946d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana return; 947d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 948f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana String authToken = result.getString(AccountManager.KEY_AUTHTOKEN); 94926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana if (authToken != null) { 950f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana String name = result.getString(AccountManager.KEY_ACCOUNT_NAME); 951f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana String type = result.getString(AccountManager.KEY_ACCOUNT_TYPE); 95226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana if (TextUtils.isEmpty(type) || TextUtils.isEmpty(name)) { 953f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana onError(AccountManager.ERROR_CODE_INVALID_RESPONSE, 95426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana "the type and name should not be empty"); 95526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana return; 95626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 957a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache if (!customTokens) { 958a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache saveAuthTokenToDatabase(new Account(name, type), 959a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache authTokenType, authToken); 960a40c6304deb860f10a51ce950ac1abc21a23d08bCostin Manolache } 961a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 962603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 963f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana Intent intent = result.getParcelable(AccountManager.KEY_INTENT); 96426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana if (intent != null && notifyOnAuthFailure) { 965d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana doNotification( 966f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana account, result.getString(AccountManager.KEY_AUTH_FAILED_MESSAGE), 96726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana intent); 96826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 969a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 97026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana super.onResult(result); 971a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 97226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana }.bind(); 97326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 97426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 97526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 976603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 977603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 978d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private void createNoCredentialsPermissionNotification(Account account, Intent intent) { 979d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana int uid = intent.getIntExtra( 980d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana GrantCredentialsPermissionActivity.EXTRAS_REQUESTING_UID, -1); 981d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana String authTokenType = intent.getStringExtra( 982d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana GrantCredentialsPermissionActivity.EXTRAS_AUTH_TOKEN_TYPE); 983d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana String authTokenLabel = intent.getStringExtra( 984d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana GrantCredentialsPermissionActivity.EXTRAS_AUTH_TOKEN_LABEL); 985d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 986d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Notification n = new Notification(android.R.drawable.stat_sys_warning, null, 987d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 0 /* when */); 988ee452ee5359cdfa3c3fbf6783722d3aaa2ec5ca6Eric Fischer final String titleAndSubtitle = 989ee452ee5359cdfa3c3fbf6783722d3aaa2ec5ca6Eric Fischer mContext.getString(R.string.permission_request_notification_with_subtitle, 990ee452ee5359cdfa3c3fbf6783722d3aaa2ec5ca6Eric Fischer account.name); 991ee452ee5359cdfa3c3fbf6783722d3aaa2ec5ca6Eric Fischer final int index = titleAndSubtitle.indexOf('\n'); 992ee452ee5359cdfa3c3fbf6783722d3aaa2ec5ca6Eric Fischer final String title = titleAndSubtitle.substring(0, index); 993ee452ee5359cdfa3c3fbf6783722d3aaa2ec5ca6Eric Fischer final String subtitle = titleAndSubtitle.substring(index + 1); 994d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana n.setLatestEventInfo(mContext, 995ee452ee5359cdfa3c3fbf6783722d3aaa2ec5ca6Eric Fischer title, subtitle, 996d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana PendingIntent.getActivity(mContext, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT)); 99756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana installNotification(getCredentialPermissionNotificationId(account, authTokenType, uid), n); 998d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 999d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 10005f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache String getAccountLabel(String accountType) { 1001d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana RegisteredServicesCache.ServiceInfo<AuthenticatorDescription> serviceInfo = 10025f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache mAuthenticatorCache.getServiceInfo( 10035f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache AuthenticatorDescription.newKey(accountType)); 1004d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (serviceInfo == null) { 10055f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache throw new IllegalArgumentException("unknown account type: " + accountType); 1006d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1007d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 1008d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana final Context authContext; 1009d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana try { 1010d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana authContext = mContext.createPackageContext( 10115f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache serviceInfo.type.packageName, 0); 1012d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } catch (PackageManager.NameNotFoundException e) { 10135f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache throw new IllegalArgumentException("unknown account type: " + accountType); 1014d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 10155f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache return authContext.getString(serviceInfo.type.labelId); 10165f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache } 10175f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache 10185f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache private Intent newGrantCredentialsPermissionIntent(Account account, int uid, 10195f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache AccountAuthenticatorResponse response, String authTokenType, String authTokenLabel) { 1020d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 1021d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Intent intent = new Intent(mContext, GrantCredentialsPermissionActivity.class); 10229ec17366c17efd14c643ee88fa1132ab05197349Costin Manolache // See FLAT_ACTIVITY_NEW_TASK docs for limitations and benefits of the flag. 10239ec17366c17efd14c643ee88fa1132ab05197349Costin Manolache // Since it was set in Eclair+ we can't change it without breaking apps using 10249ec17366c17efd14c643ee88fa1132ab05197349Costin Manolache // the intent from a non-Activity context. 10259ec17366c17efd14c643ee88fa1132ab05197349Costin Manolache intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 1026d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana intent.addCategory( 1027d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana String.valueOf(getCredentialPermissionNotificationId(account, authTokenType, uid))); 10285f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache 1029d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana intent.putExtra(GrantCredentialsPermissionActivity.EXTRAS_ACCOUNT, account); 1030d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana intent.putExtra(GrantCredentialsPermissionActivity.EXTRAS_AUTH_TOKEN_TYPE, authTokenType); 1031d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana intent.putExtra(GrantCredentialsPermissionActivity.EXTRAS_RESPONSE, response); 1032d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana intent.putExtra(GrantCredentialsPermissionActivity.EXTRAS_REQUESTING_UID, uid); 10335f383ad9695a62d6c1aeb97c8e550d7fffe26244Costin Manolache 1034d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana return intent; 1035d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1036d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 1037d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private Integer getCredentialPermissionNotificationId(Account account, String authTokenType, 1038d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana int uid) { 1039d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Integer id; 1040d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana synchronized(mCredentialsPermissionNotificationIds) { 1041d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana final Pair<Pair<Account, String>, Integer> key = 1042d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana new Pair<Pair<Account, String>, Integer>( 1043d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana new Pair<Account, String>(account, authTokenType), uid); 1044d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana id = mCredentialsPermissionNotificationIds.get(key); 1045d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (id == null) { 1046d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana id = mNotificationIds.incrementAndGet(); 1047d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana mCredentialsPermissionNotificationIds.put(key, id); 1048d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1049d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1050d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana return id; 1051d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1052d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 1053d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private Integer getSigninRequiredNotificationId(Account account) { 1054d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Integer id; 1055d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana synchronized(mSigninRequiredNotificationIds) { 1056d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana id = mSigninRequiredNotificationIds.get(account); 1057d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (id == null) { 1058d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana id = mNotificationIds.incrementAndGet(); 1059d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana mSigninRequiredNotificationIds.put(account, id); 1060d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1061d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1062d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana return id; 1063d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1064d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 10653326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana public void addAcount(final IAccountManagerResponse response, final String accountType, 10663326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana final String authTokenType, final String[] requiredFeatures, 1067a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana final boolean expectActivityLaunch, final Bundle options) { 106856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 106956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "addAccount: accountType " + accountType 107056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", response " + response 107156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", authTokenType " + authTokenType 107256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", requiredFeatures " + stringArrayToString(requiredFeatures) 107356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", expectActivityLaunch " + expectActivityLaunch 107456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 107556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 107656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 1077382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (response == null) throw new IllegalArgumentException("response is null"); 1078382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (accountType == null) throw new IllegalArgumentException("accountType is null"); 1079d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkManageAccountsPermission(); 108026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 108126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 10828570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana new Session(response, accountType, expectActivityLaunch, 10838570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana true /* stripAuthTokenFromResult */) { 108426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana public void run() throws RemoteException { 10853348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache mAuthenticator.addAccount(this, mAccountType, authTokenType, requiredFeatures, 10863326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana options); 108726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1088a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 108926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana protected String toDebugString(long now) { 109026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana return super.toDebugString(now) + ", addAccount" 10913326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + ", accountType " + accountType 10923326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + ", requiredFeatures " 10933326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + (requiredFeatures != null 10943326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana ? TextUtils.join(",", requiredFeatures) 10953326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana : null); 109626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 109726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana }.bind(); 109826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 109926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 110026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1101603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1102603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1103a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void confirmCredentials(IAccountManagerResponse response, 1104f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana final Account account, final Bundle options, final boolean expectActivityLaunch) { 110556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 110656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "confirmCredentials: " + account 110756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", response " + response 110856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", expectActivityLaunch " + expectActivityLaunch 110956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 111056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 111156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 1112382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (response == null) throw new IllegalArgumentException("response is null"); 1113382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 1114d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkManageAccountsPermission(); 111526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 111626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 11178570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana new Session(response, account.type, expectActivityLaunch, 11188570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana true /* stripAuthTokenFromResult */) { 111926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana public void run() throws RemoteException { 1120f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana mAuthenticator.confirmCredentials(this, account, options); 112126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 112226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana protected String toDebugString(long now) { 112326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana return super.toDebugString(now) + ", confirmCredentials" 112426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana + ", " + account; 112526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 112626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana }.bind(); 112726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 112826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 112926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1130603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1131603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1132a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void updateCredentials(IAccountManagerResponse response, final Account account, 1133a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana final String authTokenType, final boolean expectActivityLaunch, 1134a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana final Bundle loginOptions) { 113556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 113656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "updateCredentials: " + account 113756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", response " + response 113856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", authTokenType " + authTokenType 113956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", expectActivityLaunch " + expectActivityLaunch 114056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 114156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 114256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 1143382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (response == null) throw new IllegalArgumentException("response is null"); 1144382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 1145382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null"); 1146d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkManageAccountsPermission(); 114726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 114826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 11498570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana new Session(response, account.type, expectActivityLaunch, 11508570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana true /* stripAuthTokenFromResult */) { 115126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana public void run() throws RemoteException { 115226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana mAuthenticator.updateCredentials(this, account, authTokenType, loginOptions); 115326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 115426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana protected String toDebugString(long now) { 115526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana if (loginOptions != null) loginOptions.keySet(); 115626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana return super.toDebugString(now) + ", updateCredentials" 115726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana + ", " + account 115826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana + ", authTokenType " + authTokenType 115926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana + ", loginOptions " + loginOptions; 116026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 116126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana }.bind(); 116226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 116326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 116426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1165603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1166603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1167a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void editProperties(IAccountManagerResponse response, final String accountType, 1168a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana final boolean expectActivityLaunch) { 116956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 117056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "editProperties: accountType " + accountType 117156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", response " + response 117256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", expectActivityLaunch " + expectActivityLaunch 117356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 117456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 117556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 1176382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (response == null) throw new IllegalArgumentException("response is null"); 1177382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (accountType == null) throw new IllegalArgumentException("accountType is null"); 1178d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkManageAccountsPermission(); 117926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 118026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 11818570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana new Session(response, accountType, expectActivityLaunch, 11828570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana true /* stripAuthTokenFromResult */) { 118326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana public void run() throws RemoteException { 118426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana mAuthenticator.editProperties(this, mAccountType); 118526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 118626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana protected String toDebugString(long now) { 118726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana return super.toDebugString(now) + ", editProperties" 118826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana + ", accountType " + accountType; 118926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 119026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana }.bind(); 119126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 119226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 119326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1194603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1195603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 11963326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana private class GetAccountsByTypeAndFeatureSession extends Session { 11973326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana private final String[] mFeatures; 11983326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana private volatile Account[] mAccountsOfType = null; 11993326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana private volatile ArrayList<Account> mAccountsWithFeatures = null; 12003326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana private volatile int mCurrentAccount = 0; 12013326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 12023326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana public GetAccountsByTypeAndFeatureSession(IAccountManagerResponse response, 12033326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana String type, String[] features) { 12048570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana super(response, type, false /* expectActivityLaunch */, 12058570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana true /* stripAuthTokenFromResult */); 12063326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana mFeatures = features; 12073326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 12083326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 12093326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana public void run() throws RemoteException { 121056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana mAccountsOfType = getAccountsByTypeFromCache(mAccountType); 12113326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana // check whether each account matches the requested features 12123326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana mAccountsWithFeatures = new ArrayList<Account>(mAccountsOfType.length); 12133326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana mCurrentAccount = 0; 12143326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 12153326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana checkAccount(); 12163326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 12173326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 12183326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana public void checkAccount() { 12193326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana if (mCurrentAccount >= mAccountsOfType.length) { 12203326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana sendResult(); 12213326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana return; 12223326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 12233326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 122429e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana final IAccountAuthenticator accountAuthenticator = mAuthenticator; 122529e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana if (accountAuthenticator == null) { 122629e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana // It is possible that the authenticator has died, which is indicated by 122729e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana // mAuthenticator being set to null. If this happens then just abort. 122829e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana // There is no need to send back a result or error in this case since 122929e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana // that already happened when mAuthenticator was cleared. 123029e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 123129e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana Log.v(TAG, "checkAccount: aborting session since we are no longer" 123229e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana + " connected to the authenticator, " + toDebugString()); 123329e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana } 123429e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana return; 123529e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana } 12363326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana try { 123729e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana accountAuthenticator.hasFeatures(this, mAccountsOfType[mCurrentAccount], mFeatures); 12383326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } catch (RemoteException e) { 1239f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana onError(AccountManager.ERROR_CODE_REMOTE_EXCEPTION, "remote exception"); 1240a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1241603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1242603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 12433326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana public void onResult(Bundle result) { 12443326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana mNumResults++; 12453326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana if (result == null) { 1246f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana onError(AccountManager.ERROR_CODE_INVALID_RESPONSE, "null bundle"); 12473326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana return; 12483326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 1249f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana if (result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT, false)) { 12503326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana mAccountsWithFeatures.add(mAccountsOfType[mCurrentAccount]); 12513326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 12523326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana mCurrentAccount++; 12533326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana checkAccount(); 1254a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 12553326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 12563326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana public void sendResult() { 12573326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana IAccountManagerResponse response = getResponseAndClose(); 12583326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana if (response != null) { 12593326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana try { 12603326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana Account[] accounts = new Account[mAccountsWithFeatures.size()]; 12613326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana for (int i = 0; i < accounts.length; i++) { 12623326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana accounts[i] = mAccountsWithFeatures.get(i); 12633326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 126456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 126556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, getClass().getSimpleName() + " calling onResult() on response " 126656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + response); 126756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 12683326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana Bundle result = new Bundle(); 1269f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana result.putParcelableArray(AccountManager.KEY_ACCOUNTS, accounts); 12703326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana response.onResult(result); 12713326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } catch (RemoteException e) { 12723326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana // if the caller is dead then there is no one to care about remote exceptions 12733326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 12743326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana Log.v(TAG, "failure while notifying response", e); 12753326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 12763326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 12773326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 12783326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 12793326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 12803326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 12813326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana protected String toDebugString(long now) { 12823326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana return super.toDebugString(now) + ", getAccountsByTypeAndFeatures" 12833326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + ", " + (mFeatures != null ? TextUtils.join(",", mFeatures) : null); 12843326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 12853326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 1286ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 1287ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana public Account[] getAccounts(String type) { 128856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 128956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "getAccounts: accountType " + type 129056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 129156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 129256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 1293ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana checkReadAccountsPermission(); 1294ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana long identityToken = clearCallingIdentity(); 1295ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana try { 129656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana return getAccountsByTypeFromCache(type); 1297ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } finally { 1298ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana restoreCallingIdentity(identityToken); 1299ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 1300ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 1301ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 1302ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana public void getAccountsByFeatures(IAccountManagerResponse response, 13033326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana String type, String[] features) { 130456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 130556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, "getAccounts: accountType " + type 130656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", response " + response 130756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", features " + stringArrayToString(features) 130856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", caller's uid " + Binder.getCallingUid() 130956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + ", pid " + Binder.getCallingPid()); 131056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 1311382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (response == null) throw new IllegalArgumentException("response is null"); 1312382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (type == null) throw new IllegalArgumentException("accountType is null"); 1313d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkReadAccountsPermission(); 13143326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana long identityToken = clearCallingIdentity(); 13153326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana try { 1316ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana if (features == null || features.length == 0) { 131756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Account[] accounts = getAccountsByTypeFromCache(type); 1318d4a9d6c42bb412e27a8383aaacd051419d98a662Fred Quintana Bundle result = new Bundle(); 1319d4a9d6c42bb412e27a8383aaacd051419d98a662Fred Quintana result.putParcelableArray(AccountManager.KEY_ACCOUNTS, accounts); 1320d4a9d6c42bb412e27a8383aaacd051419d98a662Fred Quintana onResult(response, result); 1321ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana return; 1322ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 13233326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana new GetAccountsByTypeAndFeatureSession(response, type, features).bind(); 13243326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } finally { 13253326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana restoreCallingIdentity(identityToken); 13263326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 13273326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 13283326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 1329603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private long getAccountId(SQLiteDatabase db, Account account) { 1330603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana Cursor cursor = db.query(TABLE_ACCOUNTS, new String[]{ACCOUNTS_ID}, 1331ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana "name=? AND type=?", new String[]{account.name, account.type}, null, null, null); 1332603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana try { 1333603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana if (cursor.moveToNext()) { 1334603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana return cursor.getLong(0); 1335603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1336603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana return -1; 1337603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } finally { 1338603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana cursor.close(); 1339603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1340603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1341603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1342603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private long getExtrasId(SQLiteDatabase db, long accountId, String key) { 1343603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana Cursor cursor = db.query(TABLE_EXTRAS, new String[]{EXTRAS_ID}, 1344603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana EXTRAS_ACCOUNTS_ID + "=" + accountId + " AND " + EXTRAS_KEY + "=?", 1345603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana new String[]{key}, null, null, null); 1346603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana try { 1347603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana if (cursor.moveToNext()) { 1348603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana return cursor.getLong(0); 1349603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1350603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana return -1; 1351603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } finally { 1352603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana cursor.close(); 1353603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1354603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1355603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1356a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana private abstract class Session extends IAccountAuthenticatorResponse.Stub 1357b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana implements IBinder.DeathRecipient, ServiceConnection { 1358603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana IAccountManagerResponse mResponse; 1359603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana final String mAccountType; 1360a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana final boolean mExpectActivityLaunch; 1361a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana final long mCreationTime; 1362a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 13633326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana public int mNumResults = 0; 1364a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana private int mNumRequestContinued = 0; 1365a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana private int mNumErrors = 0; 1366a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 1367603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1368603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana IAccountAuthenticator mAuthenticator = null; 1369603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 13708570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana private final boolean mStripAuthTokenFromResult; 13718570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana 1372a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public Session(IAccountManagerResponse response, String accountType, 13738570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana boolean expectActivityLaunch, boolean stripAuthTokenFromResult) { 1374603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana super(); 1375a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (response == null) throw new IllegalArgumentException("response is null"); 13763326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana if (accountType == null) throw new IllegalArgumentException("accountType is null"); 13778570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana mStripAuthTokenFromResult = stripAuthTokenFromResult; 1378603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mResponse = response; 1379603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mAccountType = accountType; 1380a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana mExpectActivityLaunch = expectActivityLaunch; 1381a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana mCreationTime = SystemClock.elapsedRealtime(); 1382a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana synchronized (mSessions) { 1383a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana mSessions.put(toString(), this); 1384a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1385a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana try { 1386a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana response.asBinder().linkToDeath(this, 0 /* flags */); 1387a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } catch (RemoteException e) { 1388a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana mResponse = null; 1389a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana binderDied(); 1390a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1391603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1392603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1393a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana IAccountManagerResponse getResponseAndClose() { 1394603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana if (mResponse == null) { 1395603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana // this session has already been closed 1396603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana return null; 1397603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1398a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana IAccountManagerResponse response = mResponse; 1399a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana close(); // this clears mResponse so we need to save the response before this call 1400a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana return response; 1401a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1402a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 1403a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana private void close() { 1404a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana synchronized (mSessions) { 1405a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (mSessions.remove(toString()) == null) { 1406a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana // the session was already closed, so bail out now 1407a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana return; 1408a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1409a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1410a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (mResponse != null) { 1411a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana // stop listening for response deaths 1412a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana mResponse.asBinder().unlinkToDeath(this, 0 /* flags */); 1413a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 1414a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana // clear this so that we don't accidentally send any further results 1415a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana mResponse = null; 1416a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1417603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana cancelTimeout(); 1418603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana unbind(); 1419a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1420a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 1421a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void binderDied() { 1422603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mResponse = null; 1423a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana close(); 1424a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1425a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 1426a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana protected String toDebugString() { 1427a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana return toDebugString(SystemClock.elapsedRealtime()); 1428a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1429a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 1430a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana protected String toDebugString(long now) { 1431a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana return "Session: expectLaunch " + mExpectActivityLaunch 1432a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + ", connected " + (mAuthenticator != null) 1433a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + ", stats (" + mNumResults + "/" + mNumRequestContinued 1434a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + "/" + mNumErrors + ")" 1435a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + ", lifetime " + ((now - mCreationTime) / 1000.0); 1436603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1437603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1438603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana void bind() { 1439a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 1440a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana Log.v(TAG, "initiating bind to authenticator type " + mAccountType); 1441a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1442b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana if (!bindToAuthenticator(mAccountType)) { 1443a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana Log.d(TAG, "bind attempt failed for " + toDebugString()); 1444f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana onError(AccountManager.ERROR_CODE_REMOTE_EXCEPTION, "bind failure"); 1445603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1446603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1447603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1448603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private void unbind() { 1449603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana if (mAuthenticator != null) { 1450603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mAuthenticator = null; 1451b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana mContext.unbindService(this); 1452603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1453603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1454603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1455603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public void scheduleTimeout() { 1456603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mMessageHandler.sendMessageDelayed( 1457603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mMessageHandler.obtainMessage(MESSAGE_TIMED_OUT, this), TIMEOUT_DELAY_MS); 1458603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1459603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1460603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public void cancelTimeout() { 1461603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mMessageHandler.removeMessages(MESSAGE_TIMED_OUT, this); 1462603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1463603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1464b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana public void onServiceConnected(ComponentName name, IBinder service) { 1465603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mAuthenticator = IAccountAuthenticator.Stub.asInterface(service); 1466a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana try { 1467a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana run(); 1468a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } catch (RemoteException e) { 1469f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana onError(AccountManager.ERROR_CODE_REMOTE_EXCEPTION, 1470a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana "remote exception"); 1471a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1472603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1473603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1474b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana public void onServiceDisconnected(ComponentName name) { 1475a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana mAuthenticator = null; 1476a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana IAccountManagerResponse response = getResponseAndClose(); 1477603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana if (response != null) { 1478f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana onError(AccountManager.ERROR_CODE_REMOTE_EXCEPTION, 1479a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana "disconnected"); 1480603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1481603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1482603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1483b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana public abstract void run() throws RemoteException; 1484b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana 1485603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public void onTimedOut() { 1486a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana IAccountManagerResponse response = getResponseAndClose(); 1487603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana if (response != null) { 1488f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana onError(AccountManager.ERROR_CODE_REMOTE_EXCEPTION, 1489a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana "timeout"); 1490603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1491603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1492603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1493a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void onResult(Bundle result) { 1494a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana mNumResults++; 1495f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana if (result != null && !TextUtils.isEmpty(result.getString(AccountManager.KEY_AUTHTOKEN))) { 1496f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana String accountName = result.getString(AccountManager.KEY_ACCOUNT_NAME); 1497f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana String accountType = result.getString(AccountManager.KEY_ACCOUNT_TYPE); 1498d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (!TextUtils.isEmpty(accountName) && !TextUtils.isEmpty(accountType)) { 1499d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Account account = new Account(accountName, accountType); 1500d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana cancelNotification(getSigninRequiredNotificationId(account)); 1501d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1502603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1503a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana IAccountManagerResponse response; 1504a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (mExpectActivityLaunch && result != null 1505f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana && result.containsKey(AccountManager.KEY_INTENT)) { 1506a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana response = mResponse; 1507a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } else { 1508a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana response = getResponseAndClose(); 1509603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1510603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana if (response != null) { 1511603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana try { 1512a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (result == null) { 151356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 151456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, getClass().getSimpleName() 151556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + " calling onError() on response " + response); 151656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 1517f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana response.onError(AccountManager.ERROR_CODE_INVALID_RESPONSE, 1518a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana "null bundle returned"); 1519a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } else { 15208570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana if (mStripAuthTokenFromResult) { 15218570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana result.remove(AccountManager.KEY_AUTHTOKEN); 15228570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana } 152356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 152456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, getClass().getSimpleName() 152556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + " calling onResult() on response " + response); 152656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 1527a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana response.onResult(result); 1528a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1529603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } catch (RemoteException e) { 1530a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana // if the caller is dead then there is no one to care about remote exceptions 1531a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 1532a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana Log.v(TAG, "failure while notifying response", e); 1533a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1534603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1535603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1536603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1537603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1538a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void onRequestContinued() { 1539a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana mNumRequestContinued++; 1540603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1541603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1542603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public void onError(int errorCode, String errorMessage) { 1543a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana mNumErrors++; 1544a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana IAccountManagerResponse response = getResponseAndClose(); 1545a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (response != null) { 1546a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 154756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, getClass().getSimpleName() 154856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + " calling onError() on response " + response); 1549a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1550a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana try { 1551a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana response.onError(errorCode, errorMessage); 1552a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } catch (RemoteException e) { 1553a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 1554a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana Log.v(TAG, "Session.onError: caught RemoteException while responding", e); 1555a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1556a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1557a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } else { 1558a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 1559a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana Log.v(TAG, "Session.onError: already closed"); 1560a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1561603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1562603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1563b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana 1564b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana /** 1565b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana * find the component name for the authenticator and initiate a bind 1566b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana * if no authenticator or the bind fails then return false, otherwise return true 1567b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana */ 1568b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana private boolean bindToAuthenticator(String authenticatorType) { 1569b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana AccountAuthenticatorCache.ServiceInfo<AuthenticatorDescription> authenticatorInfo = 1570b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana mAuthenticatorCache.getServiceInfo( 1571b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana AuthenticatorDescription.newKey(authenticatorType)); 1572b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana if (authenticatorInfo == null) { 1573b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 1574b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana Log.v(TAG, "there is no authenticator for " + authenticatorType 1575b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana + ", bailing out"); 1576b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana } 1577b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana return false; 1578b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana } 1579b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana 1580b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana Intent intent = new Intent(); 1581b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana intent.setAction(AccountManager.ACTION_AUTHENTICATOR_INTENT); 1582b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana intent.setComponent(authenticatorInfo.componentName); 1583b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 1584b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana Log.v(TAG, "performing bindService to " + authenticatorInfo.componentName); 1585b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana } 1586b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana if (!mContext.bindService(intent, this, Context.BIND_AUTO_CREATE)) { 1587b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 1588b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana Log.v(TAG, "bindService to " + authenticatorInfo.componentName + " failed"); 1589b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana } 1590b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana return false; 1591b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana } 1592b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana 1593b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana 1594b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana return true; 1595b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana } 1596603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1597603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1598603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private class MessageHandler extends Handler { 1599603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana MessageHandler(Looper looper) { 1600603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana super(looper); 1601603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 16023348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache 1603603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public void handleMessage(Message msg) { 1604603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana switch (msg.what) { 1605603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana case MESSAGE_TIMED_OUT: 1606603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana Session session = (Session)msg.obj; 1607603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana session.onTimedOut(); 1608603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana break; 1609603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1610603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana default: 1611603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana throw new IllegalStateException("unhandled message: " + msg.what); 1612603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1613603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1614603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1615603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1616a8529f68671a8a118751cb6ad577f44eaf076b96Oscar Montemayor private static String getDatabaseName() { 1617a8529f68671a8a118751cb6ad577f44eaf076b96Oscar Montemayor if(Environment.isEncryptedFilesystemEnabled()) { 1618a8529f68671a8a118751cb6ad577f44eaf076b96Oscar Montemayor // Hard-coded path in case of encrypted file system 1619a8529f68671a8a118751cb6ad577f44eaf076b96Oscar Montemayor return Environment.getSystemSecureDirectory().getPath() + File.separator + DATABASE_NAME; 1620a8529f68671a8a118751cb6ad577f44eaf076b96Oscar Montemayor } else { 1621a8529f68671a8a118751cb6ad577f44eaf076b96Oscar Montemayor // Regular path in case of non-encrypted file system 1622a8529f68671a8a118751cb6ad577f44eaf076b96Oscar Montemayor return DATABASE_NAME; 1623a8529f68671a8a118751cb6ad577f44eaf076b96Oscar Montemayor } 1624a8529f68671a8a118751cb6ad577f44eaf076b96Oscar Montemayor } 1625a8529f68671a8a118751cb6ad577f44eaf076b96Oscar Montemayor 1626603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private class DatabaseHelper extends SQLiteOpenHelper { 1627a8529f68671a8a118751cb6ad577f44eaf076b96Oscar Montemayor 1628603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public DatabaseHelper(Context context) { 1629a8529f68671a8a118751cb6ad577f44eaf076b96Oscar Montemayor super(context, AccountManagerService.getDatabaseName(), null, DATABASE_VERSION); 1630603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1631603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1632603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana @Override 1633603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public void onCreate(SQLiteDatabase db) { 1634603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana db.execSQL("CREATE TABLE " + TABLE_ACCOUNTS + " ( " 1635603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + ACCOUNTS_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " 1636603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + ACCOUNTS_NAME + " TEXT NOT NULL, " 1637603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + ACCOUNTS_TYPE + " TEXT NOT NULL, " 1638603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + ACCOUNTS_PASSWORD + " TEXT, " 1639603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + "UNIQUE(" + ACCOUNTS_NAME + "," + ACCOUNTS_TYPE + "))"); 1640603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1641603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana db.execSQL("CREATE TABLE " + TABLE_AUTHTOKENS + " ( " 1642603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + AUTHTOKENS_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " 1643603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + AUTHTOKENS_ACCOUNTS_ID + " INTEGER NOT NULL, " 1644603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + AUTHTOKENS_TYPE + " TEXT NOT NULL, " 1645603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + AUTHTOKENS_AUTHTOKEN + " TEXT, " 1646603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + "UNIQUE (" + AUTHTOKENS_ACCOUNTS_ID + "," + AUTHTOKENS_TYPE + "))"); 1647603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1648d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana createGrantsTable(db); 1649d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 1650603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana db.execSQL("CREATE TABLE " + TABLE_EXTRAS + " ( " 1651603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + EXTRAS_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " 1652603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + EXTRAS_ACCOUNTS_ID + " INTEGER, " 1653603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + EXTRAS_KEY + " TEXT NOT NULL, " 1654603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + EXTRAS_VALUE + " TEXT, " 1655603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + "UNIQUE(" + EXTRAS_ACCOUNTS_ID + "," + EXTRAS_KEY + "))"); 1656603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1657603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana db.execSQL("CREATE TABLE " + TABLE_META + " ( " 1658603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + META_KEY + " TEXT PRIMARY KEY NOT NULL, " 1659603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + META_VALUE + " TEXT)"); 1660a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 1661d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana createAccountsDeletionTrigger(db); 1662d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1663d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 1664d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private void createAccountsDeletionTrigger(SQLiteDatabase db) { 1665a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana db.execSQL("" 1666a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + " CREATE TRIGGER " + TABLE_ACCOUNTS + "Delete DELETE ON " + TABLE_ACCOUNTS 1667a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + " BEGIN" 1668a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + " DELETE FROM " + TABLE_AUTHTOKENS 1669a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + " WHERE " + AUTHTOKENS_ACCOUNTS_ID + "=OLD." + ACCOUNTS_ID + " ;" 1670a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + " DELETE FROM " + TABLE_EXTRAS 1671a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + " WHERE " + EXTRAS_ACCOUNTS_ID + "=OLD." + ACCOUNTS_ID + " ;" 1672d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + " DELETE FROM " + TABLE_GRANTS 1673d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + " WHERE " + GRANTS_ACCOUNTS_ID + "=OLD." + ACCOUNTS_ID + " ;" 1674a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + " END"); 1675603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1676603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1677d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private void createGrantsTable(SQLiteDatabase db) { 1678d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana db.execSQL("CREATE TABLE " + TABLE_GRANTS + " ( " 1679d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + GRANTS_ACCOUNTS_ID + " INTEGER NOT NULL, " 1680d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + GRANTS_AUTH_TOKEN_TYPE + " STRING NOT NULL, " 1681d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + GRANTS_GRANTEE_UID + " INTEGER NOT NULL, " 1682d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + "UNIQUE (" + GRANTS_ACCOUNTS_ID + "," + GRANTS_AUTH_TOKEN_TYPE 1683d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + "," + GRANTS_GRANTEE_UID + "))"); 1684d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1685d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 1686603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana @Override 1687603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 1688a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana Log.e(TAG, "upgrade from version " + oldVersion + " to version " + newVersion); 1689603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1690a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (oldVersion == 1) { 1691d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana // no longer need to do anything since the work is done 1692d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana // when upgrading from version 2 1693d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana oldVersion++; 1694d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1695d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 1696d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (oldVersion == 2) { 1697d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana createGrantsTable(db); 1698d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana db.execSQL("DROP TRIGGER " + TABLE_ACCOUNTS + "Delete"); 1699d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana createAccountsDeletionTrigger(db); 1700a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana oldVersion++; 1701a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 17023348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache 17033348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache if (oldVersion == 3) { 17043348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache db.execSQL("UPDATE " + TABLE_ACCOUNTS + " SET " + ACCOUNTS_TYPE + 17053348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache " = 'com.google' WHERE " + ACCOUNTS_TYPE + " == 'com.google.GAIA'"); 17063348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache oldVersion++; 17073348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache } 1708603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1709603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1710603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana @Override 1711603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public void onOpen(SQLiteDatabase db) { 1712603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "opened database " + DATABASE_NAME); 1713603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1714603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1715603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1716603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private void setMetaValue(String key, String value) { 1717603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana ContentValues values = new ContentValues(); 1718603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana values.put(META_KEY, key); 1719603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana values.put(META_VALUE, value); 1720603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mOpenHelper.getWritableDatabase().replace(TABLE_META, META_KEY, values); 1721603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1722603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1723603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private String getMetaValue(String key) { 1724603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana Cursor c = mOpenHelper.getReadableDatabase().query(TABLE_META, 1725603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana new String[]{META_VALUE}, META_KEY + "=?", new String[]{key}, null, null, null); 1726603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana try { 1727603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana if (c.moveToNext()) { 1728603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana return c.getString(0); 1729603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1730603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana return null; 1731603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } finally { 1732603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana c.close(); 1733603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1734603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1735603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1736603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private class SimWatcher extends BroadcastReceiver { 1737603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public SimWatcher(Context context) { 1738603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana // Re-scan the SIM card when the SIM state changes, and also if 1739603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana // the disk recovers from a full state (we may have failed to handle 1740603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana // things properly while the disk was full). 1741603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana final IntentFilter filter = new IntentFilter(); 1742603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED); 1743603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana filter.addAction(Intent.ACTION_DEVICE_STORAGE_OK); 1744603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana context.registerReceiver(this, filter); 1745603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 17463348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache 1747603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana /** 1748603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * Compare the IMSI to the one stored in the login service's 1749603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * database. If they differ, erase all passwords and 1750603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * authtokens (and store the new IMSI). 1751603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana */ 1752603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana @Override 1753603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public void onReceive(Context context, Intent intent) { 1754885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker // Check IMSI on every update; nothing happens if the IMSI 1755885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker // is missing or unchanged. 1756885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker TelephonyManager telephonyManager = 1757885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); 1758885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker if (telephonyManager == null) { 1759885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker Log.w(TAG, "failed to get TelephonyManager"); 1760885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker return; 1761885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker } 1762885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker String imsi = telephonyManager.getSubscriberId(); 1763885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker 1764885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker // If the subscriber ID is an empty string, don't do anything. 1765603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana if (TextUtils.isEmpty(imsi)) return; 1766603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1767885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker // If the current IMSI matches what's stored, don't do anything. 1768603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana String storedImsi = getMetaValue("imsi"); 1769603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 1770603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana Log.v(TAG, "current IMSI=" + imsi + "; stored IMSI=" + storedImsi); 1771603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1772885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker if (imsi.equals(storedImsi)) return; 1773885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker 1774885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker // If a CDMA phone is unprovisioned, getSubscriberId() 1775885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker // will return a different value, but we *don't* erase the 1776885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker // passwords. We only erase them if it has a different 1777885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker // subscriber ID once it's provisioned. 1778885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker if (telephonyManager.getPhoneType() == TelephonyManager.PHONE_TYPE_CDMA) { 1779885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker IBinder service = ServiceManager.checkService(Context.TELEPHONY_SERVICE); 1780885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker if (service == null) { 1781885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker Log.w(TAG, "call to checkService(TELEPHONY_SERVICE) failed"); 1782885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker return; 1783885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker } 1784885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker ITelephony telephony = ITelephony.Stub.asInterface(service); 1785885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker if (telephony == null) { 1786885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker Log.w(TAG, "failed to get ITelephony interface"); 1787885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker return; 1788885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker } 1789885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker boolean needsProvisioning; 1790885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker try { 17914d8ae85b5de8a90a597e4b649c6ee7208e446e3bWink Saville needsProvisioning = telephony.needsOtaServiceProvisioning(); 1792885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker } catch (RemoteException e) { 1793885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker Log.w(TAG, "exception while checking provisioning", e); 1794885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker // default to NOT wiping out the passwords 1795885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker needsProvisioning = true; 1796885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker } 1797885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker if (needsProvisioning) { 1798885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker // if the phone needs re-provisioning, don't do anything. 1799885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker if (Log.isLoggable(TAG, Log.VERBOSE)) { 1800885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker Log.v(TAG, "current IMSI=" + imsi + " (needs provisioning); stored IMSI=" + 1801885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker storedImsi); 1802885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker } 1803885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker return; 1804885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker } 1805885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker } 1806603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 18075b462477a90cd08551149fc649ff3035b5331d2djsh if (!imsi.equals(storedImsi) && !TextUtils.isEmpty(storedImsi)) { 180827844c386e5567a91ab781265ae5ad40d0ab1e27Jim Miller Log.w(TAG, "wiping all passwords and authtokens because IMSI changed (" 180927844c386e5567a91ab781265ae5ad40d0ab1e27Jim Miller + "stored=" + storedImsi + ", current=" + imsi + ")"); 1810603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana SQLiteDatabase db = mOpenHelper.getWritableDatabase(); 1811603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana db.beginTransaction(); 1812603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana try { 1813603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana db.execSQL("DELETE from " + TABLE_AUTHTOKENS); 1814603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana db.execSQL("UPDATE " + TABLE_ACCOUNTS + " SET " + ACCOUNTS_PASSWORD + " = ''"); 1815603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana db.setTransactionSuccessful(); 1816603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } finally { 1817603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana db.endTransaction(); 1818603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1819743dfad2a51e016ddb741c104317637089187753Fred Quintana sendAccountsChangedBroadcast(); 1820603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1821603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana setMetaValue("imsi", imsi); 1822603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1823603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1824603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1825603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public IBinder onBind(Intent intent) { 1826603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana return asBinder(); 1827603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1828a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 18291cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks /** 18301cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks * Searches array of arguments for the specified string 18311cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks * @param args array of argument strings 18321cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks * @param value value to search for 18331cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks * @return true if the value is contained in the array 18341cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks */ 18351cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks private static boolean scanArgs(String[] args, String value) { 18361cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks if (args != null) { 18371cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks for (String arg : args) { 18381cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks if (value.equals(arg)) { 18391cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks return true; 18401cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks } 1841a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1842a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 18431cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks return false; 18441cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks } 1845a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 18461cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) { 18471cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks final boolean isCheckinRequest = scanArgs(args, "--checkin") || scanArgs(args, "-c"); 18481cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks 18491cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks if (isCheckinRequest) { 18501cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks // This is a checkin request. *Only* upload the account types and the count of each. 18511cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks SQLiteDatabase db = mOpenHelper.getReadableDatabase(); 1852a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 18531cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks Cursor cursor = db.query(TABLE_ACCOUNTS, ACCOUNT_TYPE_COUNT_PROJECTION, 18541cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks null, null, ACCOUNTS_TYPE, null, null); 18551cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks try { 18561cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks while (cursor.moveToNext()) { 18571cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks // print type,count 18581cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks fout.println(cursor.getString(0) + "," + cursor.getString(1)); 18591cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks } 18601cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks } finally { 18611cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks if (cursor != null) { 18621cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks cursor.close(); 18631cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks } 18641cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks } 18651cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks } else { 186656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Account[] accounts = getAccountsByTypeFromCache(null /* type */); 1867307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana fout.println("Accounts: " + accounts.length); 1868307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana for (Account account : accounts) { 1869307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana fout.println(" " + account); 1870307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana } 1871307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana 1872307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana fout.println(); 18731cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks synchronized (mSessions) { 18741cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks final long now = SystemClock.elapsedRealtime(); 1875307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana fout.println("Active Sessions: " + mSessions.size()); 18761cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks for (Session session : mSessions.values()) { 18771cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks fout.println(" " + session.toDebugString(now)); 18781cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks } 18791cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks } 18801cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks 18811cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks fout.println(); 18821cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks mAuthenticatorCache.dump(fd, fout, args); 18831cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks } 1884a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1885a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 1886d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private void doNotification(Account account, CharSequence message, Intent intent) { 188726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 188826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 188926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 189026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana Log.v(TAG, "doNotification: " + message + " intent:" + intent); 189126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1892a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 1893d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (intent.getComponent() != null && 1894d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana GrantCredentialsPermissionActivity.class.getName().equals( 1895d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana intent.getComponent().getClassName())) { 1896d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana createNoCredentialsPermissionNotification(account, intent); 1897d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } else { 189833f889ae270f888f8fdc084f5f1f3d443532a46aFred Quintana final Integer notificationId = getSigninRequiredNotificationId(account); 189933f889ae270f888f8fdc084f5f1f3d443532a46aFred Quintana intent.addCategory(String.valueOf(notificationId)); 1900d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Notification n = new Notification(android.R.drawable.stat_sys_warning, null, 1901d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 0 /* when */); 190233f889ae270f888f8fdc084f5f1f3d443532a46aFred Quintana final String notificationTitleFormat = 190333f889ae270f888f8fdc084f5f1f3d443532a46aFred Quintana mContext.getText(R.string.notification_title).toString(); 190433f889ae270f888f8fdc084f5f1f3d443532a46aFred Quintana n.setLatestEventInfo(mContext, 190533f889ae270f888f8fdc084f5f1f3d443532a46aFred Quintana String.format(notificationTitleFormat, account.name), 1906d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana message, PendingIntent.getActivity( 1907d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana mContext, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT)); 190856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana installNotification(notificationId, n); 1909d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 191026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 191126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 191226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1913a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1914a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 191556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana protected void installNotification(final int notificationId, final Notification n) { 191656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana ((NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE)) 191756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana .notify(notificationId, n); 191856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 191956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 192056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana protected void cancelNotification(int id) { 192126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 192226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 192326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana ((NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE)) 1924d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana .cancel(id); 192526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 192626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 192726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1928a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1929d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 1930b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana /** Succeeds if any of the specified permissions are granted. */ 1931b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana private void checkBinderPermission(String... permissions) { 1932d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana final int uid = Binder.getCallingUid(); 1933b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana 1934b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana for (String perm : permissions) { 1935b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana if (mContext.checkCallingOrSelfPermission(perm) == PackageManager.PERMISSION_GRANTED) { 1936b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 193756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.v(TAG, " caller uid " + uid + " has " + perm); 1938b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana } 1939b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana return; 1940b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana } 1941d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1942b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana 1943b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana String msg = "caller uid " + uid + " lacks any of " + TextUtils.join(",", permissions); 194456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Log.w(TAG, " " + msg); 1945b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana throw new SecurityException(msg); 1946d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1947d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 19487be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana private boolean inSystemImage(int callerUid) { 194956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana String[] packages = mPackageManager.getPackagesForUid(callerUid); 19507be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana for (String name : packages) { 19517be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana try { 195256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana PackageInfo packageInfo = mPackageManager.getPackageInfo(name, 0 /* flags */); 195356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (packageInfo != null 195456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana && (packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 19557be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana return true; 19567be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana } 19577be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana } catch (PackageManager.NameNotFoundException e) { 19587be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana return false; 19597be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana } 19607be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana } 19617be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana return false; 19627be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana } 19637be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana 1964d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private boolean permissionIsGranted(Account account, String authTokenType, int callerUid) { 1965b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana final boolean inSystemImage = inSystemImage(callerUid); 196631957f1badbb900bbfe211317e1ea992d650a72dFred Quintana final boolean fromAuthenticator = account != null 196731957f1badbb900bbfe211317e1ea992d650a72dFred Quintana && hasAuthenticatorUid(account.type, callerUid); 196831957f1badbb900bbfe211317e1ea992d650a72dFred Quintana final boolean hasExplicitGrants = account != null 196931957f1badbb900bbfe211317e1ea992d650a72dFred Quintana && hasExplicitlyGrantedPermission(account, authTokenType); 1970d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 1971d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Log.v(TAG, "checkGrantsOrCallingUidAgainstAuthenticator: caller uid " 197256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana + callerUid + ", " + account 1973d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + ": is authenticator? " + fromAuthenticator 1974d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + ", has explicit permission? " + hasExplicitGrants); 1975d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1976b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana return fromAuthenticator || hasExplicitGrants || inSystemImage; 1977d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1978d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 19791a23191bbde11505d6e0c25c04a60b41cb27fd31Fred Quintana private boolean hasAuthenticatorUid(String accountType, int callingUid) { 1980d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana for (RegisteredServicesCache.ServiceInfo<AuthenticatorDescription> serviceInfo : 1981d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana mAuthenticatorCache.getAllServices()) { 1982d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (serviceInfo.type.type.equals(accountType)) { 1983ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana return (serviceInfo.uid == callingUid) || 198456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana (mPackageManager.checkSignatures(serviceInfo.uid, callingUid) 1985ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana == PackageManager.SIGNATURE_MATCH); 1986d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1987d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1988d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana return false; 1989d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1990d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 1991d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private boolean hasExplicitlyGrantedPermission(Account account, String authTokenType) { 1992d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (Binder.getCallingUid() == android.os.Process.SYSTEM_UID) { 1993d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana return true; 1994d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1995d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana SQLiteDatabase db = mOpenHelper.getReadableDatabase(); 1996d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana String[] args = {String.valueOf(Binder.getCallingUid()), authTokenType, 1997ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana account.name, account.type}; 1998d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana final boolean permissionGranted = 1999d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana DatabaseUtils.longForQuery(db, COUNT_OF_MATCHING_GRANTS, args) != 0; 20003b4fcbc9f13bab6a2e9e5c37cc5e18fec7341c04Brett Chabot if (!permissionGranted && ActivityManager.isRunningInTestHarness()) { 2001d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana // TODO: Skip this check when running automated tests. Replace this 2002d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana // with a more general solution. 2003751fdc09bb7ab0ce6feac7b7a823e38ed858feb0Fred Quintana Log.d(TAG, "no credentials permission for usage of " + account + ", " 2004d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + authTokenType + " by uid " + Binder.getCallingUid() 20053b4fcbc9f13bab6a2e9e5c37cc5e18fec7341c04Brett Chabot + " but ignoring since device is in test harness."); 2006d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana return true; 2007d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2008d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana return permissionGranted; 2009d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2010d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 2011d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private void checkCallingUidAgainstAuthenticator(Account account) { 2012d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana final int uid = Binder.getCallingUid(); 201331957f1badbb900bbfe211317e1ea992d650a72dFred Quintana if (account == null || !hasAuthenticatorUid(account.type, uid)) { 2014d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana String msg = "caller uid " + uid + " is different than the authenticator's uid"; 2015d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Log.w(TAG, msg); 2016d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana throw new SecurityException(msg); 2017d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2018d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 2019d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Log.v(TAG, "caller uid " + uid + " is the same as the authenticator's uid"); 2020d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2021d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2022d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 2023d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private void checkAuthenticateAccountsPermission(Account account) { 2024d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkBinderPermission(Manifest.permission.AUTHENTICATE_ACCOUNTS); 2025d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkCallingUidAgainstAuthenticator(account); 2026d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2027d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 2028d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private void checkReadAccountsPermission() { 2029d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkBinderPermission(Manifest.permission.GET_ACCOUNTS); 2030d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2031d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 2032d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private void checkManageAccountsPermission() { 2033d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkBinderPermission(Manifest.permission.MANAGE_ACCOUNTS); 2034d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2035d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 2036b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana private void checkManageAccountsOrUseCredentialsPermissions() { 2037b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana checkBinderPermission(Manifest.permission.MANAGE_ACCOUNTS, 2038b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana Manifest.permission.USE_CREDENTIALS); 2039b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana } 2040b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana 2041d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana /** 2042d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * Allow callers with the given uid permission to get credentials for account/authTokenType. 2043d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * <p> 2044d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * Although this is public it can only be accessed via the AccountManagerService object 2045d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * which is in the system. This means we don't need to protect it with permissions. 2046d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * @hide 2047d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana */ 2048d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana public void grantAppPermission(Account account, String authTokenType, int uid) { 2049382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null || authTokenType == null) { 2050382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana Log.e(TAG, "grantAppPermission: called with invalid arguments", new Exception()); 205131957f1badbb900bbfe211317e1ea992d650a72dFred Quintana return; 205231957f1badbb900bbfe211317e1ea992d650a72dFred Quintana } 2053d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana SQLiteDatabase db = mOpenHelper.getWritableDatabase(); 2054d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana db.beginTransaction(); 2055d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana try { 2056d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana long accountId = getAccountId(db, account); 2057d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (accountId >= 0) { 2058d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana ContentValues values = new ContentValues(); 2059d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana values.put(GRANTS_ACCOUNTS_ID, accountId); 2060d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana values.put(GRANTS_AUTH_TOKEN_TYPE, authTokenType); 2061d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana values.put(GRANTS_GRANTEE_UID, uid); 2062d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana db.insert(TABLE_GRANTS, GRANTS_ACCOUNTS_ID, values); 2063d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana db.setTransactionSuccessful(); 2064d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2065d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } finally { 2066d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana db.endTransaction(); 2067d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2068d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana cancelNotification(getCredentialPermissionNotificationId(account, authTokenType, uid)); 2069d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2070d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 2071d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana /** 2072d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * Don't allow callers with the given uid permission to get credentials for 2073d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * account/authTokenType. 2074d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * <p> 2075d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * Although this is public it can only be accessed via the AccountManagerService object 2076d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * which is in the system. This means we don't need to protect it with permissions. 2077d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * @hide 2078d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana */ 2079d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana public void revokeAppPermission(Account account, String authTokenType, int uid) { 2080382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null || authTokenType == null) { 2081382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana Log.e(TAG, "revokeAppPermission: called with invalid arguments", new Exception()); 208231957f1badbb900bbfe211317e1ea992d650a72dFred Quintana return; 208331957f1badbb900bbfe211317e1ea992d650a72dFred Quintana } 2084d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana SQLiteDatabase db = mOpenHelper.getWritableDatabase(); 2085d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana db.beginTransaction(); 2086d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana try { 2087d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana long accountId = getAccountId(db, account); 2088d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (accountId >= 0) { 2089d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana db.delete(TABLE_GRANTS, 2090d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana GRANTS_ACCOUNTS_ID + "=? AND " + GRANTS_AUTH_TOKEN_TYPE + "=? AND " 2091d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + GRANTS_GRANTEE_UID + "=?", 2092d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana new String[]{String.valueOf(accountId), authTokenType, 2093d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana String.valueOf(uid)}); 2094d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana db.setTransactionSuccessful(); 2095d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2096d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } finally { 2097d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana db.endTransaction(); 2098d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 2099d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana cancelNotification(getCredentialPermissionNotificationId(account, authTokenType, uid)); 2100d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 210156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 210256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana static final private String stringArrayToString(String[] value) { 210356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana return value != null ? ("[" + TextUtils.join(",", value) + "]") : null; 210456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 210556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 210656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana private void removeAccountFromCache(Account account) { 210756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana synchronized (mCacheLock) { 210856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final Account[] oldAccountsForType = mAccountCache.get(account.type); 210956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (oldAccountsForType != null) { 211056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana ArrayList<Account> newAccountsList = new ArrayList<Account>(); 211156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana for (Account curAccount : oldAccountsForType) { 211256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (!curAccount.equals(account)) { 211356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana newAccountsList.add(curAccount); 211456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 211556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 211656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (newAccountsList.isEmpty()) { 211756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana mAccountCache.remove(account.type); 211856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } else { 211956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Account[] newAccountsForType = new Account[newAccountsList.size()]; 212056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana newAccountsForType = newAccountsList.toArray(newAccountsForType); 212156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana mAccountCache.put(account.type, newAccountsForType); 212256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 212356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 212456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana mUserDataCache.remove(account); 212556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana mAuthTokenCache.remove(account); 212656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 212756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 212856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 212956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana /** 213056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana * This assumes that the caller has already checked that the account is not already present. 213156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana */ 213256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana private void insertAccountIntoCache(Account account) { 213356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana synchronized (mCacheLock) { 213456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Account[] accountsForType = mAccountCache.get(account.type); 213556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana int oldLength = (accountsForType != null) ? accountsForType.length : 0; 213656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Account[] newAccountsForType = new Account[oldLength + 1]; 213756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (accountsForType != null) { 213856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana System.arraycopy(accountsForType, 0, newAccountsForType, 0, oldLength); 213956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 214056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana newAccountsForType[oldLength] = account; 214156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana mAccountCache.put(account.type, newAccountsForType); 214256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 214356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 214456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 214556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana protected Account[] getAccountsByTypeFromCache(String accountType) { 214656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana synchronized (mCacheLock) { 214756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (accountType != null) { 214856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final Account[] accounts = mAccountCache.get(accountType); 214956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (accounts == null) { 215056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana return EMPTY_ACCOUNT_ARRAY; 215156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } else { 215256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana return Arrays.copyOf(accounts, accounts.length); 215356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 215456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } else { 215556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana int totalLength = 0; 215656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana for (Account[] accounts : mAccountCache.values()) { 215756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana totalLength += accounts.length; 215856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 215956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (totalLength == 0) { 216056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana return EMPTY_ACCOUNT_ARRAY; 216156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 216256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Account[] accounts = new Account[totalLength]; 216356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana totalLength = 0; 216456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana for (Account[] accountsOfType : mAccountCache.values()) { 216556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana System.arraycopy(accountsOfType, 0, accounts, totalLength, 216656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana accountsOfType.length); 216756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana totalLength += accountsOfType.length; 216856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 216956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana return accounts; 217056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 217156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 217256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 217356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 217456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana protected void writeUserDataIntoCache(Account account, String key, String value) { 217556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana synchronized (mCacheLock) { 217656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana HashMap<String, String> userDataForAccount = mUserDataCache.get(account); 217756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (userDataForAccount == null) { 217856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana userDataForAccount = readUserDataForAccountFromDatabase(account); 217956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana mUserDataCache.put(account, userDataForAccount); 218056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 218156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (value == null) { 218256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana userDataForAccount.remove(key); 218356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } else { 218456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana userDataForAccount.put(key, value); 218556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 218656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 218756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 218856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 218956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana protected void writeAuthTokenIntoCache(Account account, String key, String value) { 219056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana synchronized (mCacheLock) { 219156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana HashMap<String, String> authTokensForAccount = mAuthTokenCache.get(account); 219256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (authTokensForAccount == null) { 219356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana authTokensForAccount = readAuthTokensForAccountFromDatabase(account); 219456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana mAuthTokenCache.put(account, authTokensForAccount); 219556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 219656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (value == null) { 219756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana authTokensForAccount.remove(key); 219856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } else { 219956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana authTokensForAccount.put(key, value); 220056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 220156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 220256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 220356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 220456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana protected String readAuthTokenFromCache(Account account, String authTokenType) { 220556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana synchronized (mCacheLock) { 220656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana HashMap<String, String> authTokensForAccount = mAuthTokenCache.get(account); 220756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (authTokensForAccount == null) { 220856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana // need to populate the cache for this account 220956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana authTokensForAccount = readAuthTokensForAccountFromDatabase(account); 221056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana mAuthTokenCache.put(account, authTokensForAccount); 221156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 221256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana return authTokensForAccount.get(authTokenType); 221356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 221456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 221556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 221656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana protected String readUserDataFromCache(Account account, String key) { 221756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana synchronized (mCacheLock) { 221856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana HashMap<String, String> userDataForAccount = mUserDataCache.get(account); 221956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (userDataForAccount == null) { 222056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana // need to populate the cache for this account 222156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana userDataForAccount = readUserDataForAccountFromDatabase(account); 222256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana mUserDataCache.put(account, userDataForAccount); 222356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 222456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana return userDataForAccount.get(key); 222556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 222656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 222756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 222856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana protected HashMap<String, String> readUserDataForAccountFromDatabase(Account account) { 222956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana HashMap<String, String> userDataForAccount = new HashMap<String, String>(); 223056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana SQLiteDatabase db = mOpenHelper.getReadableDatabase(); 223156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Cursor cursor = db.query(TABLE_EXTRAS, 223256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana COLUMNS_EXTRAS_KEY_AND_VALUE, 223356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana SELECTION_USERDATA_BY_ACCOUNT, 223456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana new String[]{account.name, account.type}, 223556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana null, null, null); 223656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana try { 223756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana while (cursor.moveToNext()) { 223856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final String tmpkey = cursor.getString(0); 223956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final String value = cursor.getString(1); 224056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana userDataForAccount.put(tmpkey, value); 224156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 224256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } finally { 224356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana cursor.close(); 224456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 224556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana return userDataForAccount; 224656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 224756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 224856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana protected HashMap<String, String> readAuthTokensForAccountFromDatabase(Account account) { 224956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana HashMap<String, String> authTokensForAccount = new HashMap<String, String>(); 225056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana SQLiteDatabase db = mOpenHelper.getReadableDatabase(); 225156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Cursor cursor = db.query(TABLE_AUTHTOKENS, 225256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana COLUMNS_AUTHTOKENS_TYPE_AND_AUTHTOKEN, 225356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana SELECTION_AUTHTOKENS_BY_ACCOUNT, 225456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana new String[]{account.name, account.type}, 225556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana null, null, null); 225656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana try { 225756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana while (cursor.moveToNext()) { 225856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final String type = cursor.getString(0); 225956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana final String authToken = cursor.getString(1); 226056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana authTokensForAccount.put(type, authToken); 226156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 226256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } finally { 226356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana cursor.close(); 226456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 226556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana return authTokensForAccount; 226656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 2267603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana} 2268