1603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana/* 2603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * Copyright (C) 2009 The Android Open Source Project 3603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * 4603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * Licensed under the Apache License, Version 2.0 (the "License"); 5603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * you may not use this file except in compliance with the License. 6603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * You may obtain a copy of the License at 7603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * 8603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * http://www.apache.org/licenses/LICENSE-2.0 9603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * 10603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * Unless required by applicable law or agreed to in writing, software 11603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * distributed under the License is distributed on an "AS IS" BASIS, 12603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * See the License for the specific language governing permissions and 14603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * limitations under the License. 15603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana */ 16603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 17603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintanapackage android.accounts; 18603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 19885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongkerimport android.Manifest; 20885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongkerimport android.app.Notification; 21885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongkerimport android.app.NotificationManager; 22885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongkerimport android.app.PendingIntent; 23a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.content.BroadcastReceiver; 24885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongkerimport android.content.ComponentName; 25a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.content.ContentValues; 26a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.content.Context; 27a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.content.Intent; 28a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.content.IntentFilter; 29b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintanaimport android.content.ServiceConnection; 30885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongkerimport android.content.pm.ApplicationInfo; 31885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongkerimport android.content.pm.PackageInfo; 32d4a1d2e14297a3387fdb5761090961e714370492Fred Quintanaimport android.content.pm.PackageManager; 33d4a1d2e14297a3387fdb5761090961e714370492Fred Quintanaimport android.content.pm.RegisteredServicesCache; 343ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintanaimport android.content.pm.RegisteredServicesCacheListener; 35603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintanaimport android.database.Cursor; 36603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintanaimport android.database.DatabaseUtils; 37a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.database.sqlite.SQLiteDatabase; 38a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.database.sqlite.SQLiteOpenHelper; 39885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongkerimport android.os.Binder; 40a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.os.Bundle; 41a8529f68671a8a118751cb6ad577f44eaf076b96Oscar Montemayorimport android.os.Environment; 42a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.os.Handler; 43a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.os.HandlerThread; 44a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.os.IBinder; 45a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.os.Looper; 46a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.os.Message; 47a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.os.RemoteException; 48885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongkerimport android.os.ServiceManager; 49a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.os.SystemClock; 50d4a1d2e14297a3387fdb5761090961e714370492Fred Quintanaimport android.os.SystemProperties; 51603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintanaimport android.telephony.TelephonyManager; 52a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.text.TextUtils; 53a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport android.util.Log; 54d4a1d2e14297a3387fdb5761090961e714370492Fred Quintanaimport android.util.Pair; 55603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 56a8529f68671a8a118751cb6ad577f44eaf076b96Oscar Montemayorimport java.io.File; 57a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport java.io.FileDescriptor; 58a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport java.io.PrintWriter; 59a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport java.util.ArrayList; 60a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport java.util.Collection; 61a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintanaimport java.util.LinkedHashMap; 62d4a1d2e14297a3387fdb5761090961e714370492Fred Quintanaimport java.util.HashMap; 63d4a1d2e14297a3387fdb5761090961e714370492Fred Quintanaimport java.util.concurrent.atomic.AtomicInteger; 64d4a1d2e14297a3387fdb5761090961e714370492Fred Quintanaimport java.util.concurrent.atomic.AtomicReference; 65603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 6626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintanaimport com.android.internal.R; 67885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongkerimport com.android.internal.telephony.ITelephony; 68885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongkerimport com.android.internal.telephony.TelephonyIntents; 69603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 70603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana/** 71603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * A system service that provides account, password, and authtoken management for all 72603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * accounts on the device. Some of these calls are implemented with the help of the corresponding 73603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * {@link IAccountAuthenticator} services. This service is not accessed by users directly, 74603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * instead one uses an instance of {@link AccountManager}, which can be accessed as follows: 75603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * AccountManager accountManager = 76603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * (AccountManager)context.getSystemService(Context.ACCOUNT_SERVICE) 773326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana * @hide 78603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana */ 793ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintanapublic class AccountManagerService 803ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintana extends IAccountManager.Stub 815ebbb4a6b3e16f711735ae0615b9a9ea64faad38Fred Quintana implements RegisteredServicesCacheListener<AuthenticatorDescription> { 823348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache private static final String GOOGLE_ACCOUNT_TYPE = "com.google"; 8350c05f38b3728b7430dd4bb8d98565d9c5e56798Jim Miller 8450c05f38b3728b7430dd4bb8d98565d9c5e56798Jim Miller private static final String NO_BROADCAST_FLAG = "nobroadcast"; 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 94603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private HandlerThread mMessageThread; 95603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private final MessageHandler mMessageHandler; 96603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 97603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana // Messages that can be sent on mHandler 98603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final int MESSAGE_TIMED_OUT = 3; 99603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 100603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private final AccountAuthenticatorCache mAuthenticatorCache; 101603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private final DatabaseHelper mOpenHelper; 102603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private final SimWatcher mSimWatcher; 103603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 104603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String TABLE_ACCOUNTS = "accounts"; 105603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String ACCOUNTS_ID = "_id"; 106603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String ACCOUNTS_NAME = "name"; 107603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String ACCOUNTS_TYPE = "type"; 1081cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks private static final String ACCOUNTS_TYPE_COUNT = "count(type)"; 109603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String ACCOUNTS_PASSWORD = "password"; 110603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 111603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String TABLE_AUTHTOKENS = "authtokens"; 112603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String AUTHTOKENS_ID = "_id"; 113603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String AUTHTOKENS_ACCOUNTS_ID = "accounts_id"; 114603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String AUTHTOKENS_TYPE = "type"; 115603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String AUTHTOKENS_AUTHTOKEN = "authtoken"; 116603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 117d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private static final String TABLE_GRANTS = "grants"; 118d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private static final String GRANTS_ACCOUNTS_ID = "accounts_id"; 119d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private static final String GRANTS_AUTH_TOKEN_TYPE = "auth_token_type"; 120d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private static final String GRANTS_GRANTEE_UID = "uid"; 121d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 122603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String TABLE_EXTRAS = "extras"; 123603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String EXTRAS_ID = "_id"; 124603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String EXTRAS_ACCOUNTS_ID = "accounts_id"; 125603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String EXTRAS_KEY = "key"; 126603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String EXTRAS_VALUE = "value"; 127603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 128603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String TABLE_META = "meta"; 129603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String META_KEY = "key"; 130603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String META_VALUE = "value"; 131603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 132603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private static final String[] ACCOUNT_NAME_TYPE_PROJECTION = 133603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana new String[]{ACCOUNTS_ID, ACCOUNTS_NAME, ACCOUNTS_TYPE}; 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 146a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana private final LinkedHashMap<String, Session> mSessions = new LinkedHashMap<String, Session>(); 147d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private final AtomicInteger mNotificationIds = new AtomicInteger(1); 148d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 149d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private final HashMap<Pair<Pair<Account, String>, Integer>, Integer> 150d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana mCredentialsPermissionNotificationIds = 151d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana new HashMap<Pair<Pair<Account, String>, Integer>, Integer>(); 152d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private final HashMap<Account, Integer> mSigninRequiredNotificationIds = 153d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana new HashMap<Account, Integer>(); 154d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private static AtomicReference<AccountManagerService> sThis = 155d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana new AtomicReference<AccountManagerService>(); 156d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 157d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private static final boolean isDebuggableMonkeyBuild = 15842c98ada113ae5b7c72ecb6d0de721ec1d0d3534Ying Wang SystemProperties.getBoolean("ro.monkey", false); 15931957f1badbb900bbfe211317e1ea992d650a72dFred Quintana private static final Account[] EMPTY_ACCOUNT_ARRAY = new Account[]{}; 1607be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana 1617be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana static { 162f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana ACCOUNTS_CHANGED_INTENT = new Intent(AccountManager.LOGIN_ACCOUNTS_CHANGED_ACTION); 1637be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana ACCOUNTS_CHANGED_INTENT.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 1647be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana } 1657be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana 166d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana /** 167d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * This should only be called by system code. One should only call this after the service 168d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * has started. 169d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * @return a reference to the AccountManagerService instance 170d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * @hide 171d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana */ 172d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana public static AccountManagerService getSingleton() { 173d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana return sThis.get(); 174d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 175603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 176603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public class AuthTokenKey { 177603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public final Account mAccount; 178603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public final String mAuthTokenType; 179603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private final int mHashCode; 180603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 181603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public AuthTokenKey(Account account, String authTokenType) { 182603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mAccount = account; 183603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mAuthTokenType = authTokenType; 184603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mHashCode = computeHashCode(); 185603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 186603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 187603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public boolean equals(Object o) { 188603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana if (o == this) { 189603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana return true; 190603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 191603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana if (!(o instanceof AuthTokenKey)) { 192603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana return false; 193603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 194603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana AuthTokenKey other = (AuthTokenKey)o; 195603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana if (!mAccount.equals(other.mAccount)) { 196603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana return false; 197603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 198603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana return (mAuthTokenType == null) 199603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana ? other.mAuthTokenType == null 200603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana : mAuthTokenType.equals(other.mAuthTokenType); 201603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 202603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 203603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private int computeHashCode() { 204603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana int result = 17; 205603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana result = 31 * result + mAccount.hashCode(); 206603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana result = 31 * result + ((mAuthTokenType == null) ? 0 : mAuthTokenType.hashCode()); 207603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana return result; 208603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 209603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 210603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public int hashCode() { 211603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana return mHashCode; 212603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 213603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 214603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 215603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public AccountManagerService(Context context) { 216603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mContext = context; 217603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 218603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mOpenHelper = new DatabaseHelper(mContext); 219603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 220603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mMessageThread = new HandlerThread("AccountManagerService"); 221603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mMessageThread.start(); 222603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mMessageHandler = new MessageHandler(mMessageThread.getLooper()); 223603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 224603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mAuthenticatorCache = new AccountAuthenticatorCache(mContext); 2255ebbb4a6b3e16f711735ae0615b9a9ea64faad38Fred Quintana mAuthenticatorCache.setListener(this, null /* Handler */); 226603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 227885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker mSimWatcher = new SimWatcher(mContext); 228d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana sThis.set(this); 229afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana 230afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana validateAccounts(); 231afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana } 232afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana 233afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana private void validateAccounts() { 234afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana boolean accountDeleted = false; 235afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana SQLiteDatabase db = mOpenHelper.getWritableDatabase(); 236afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana Cursor cursor = db.query(TABLE_ACCOUNTS, 237afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana new String[]{ACCOUNTS_ID, ACCOUNTS_TYPE, ACCOUNTS_NAME}, 238afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana null, null, null, null, null); 239afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana try { 240afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana while (cursor.moveToNext()) { 241afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana final long accountId = cursor.getLong(0); 242afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana final String accountType = cursor.getString(1); 243afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana final String accountName = cursor.getString(2); 244afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana if (mAuthenticatorCache.getServiceInfo(AuthenticatorDescription.newKey(accountType)) 245afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana == null) { 246afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana Log.d(TAG, "deleting account " + accountName + " because type " 247afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana + accountType + " no longer has a registered authenticator"); 248afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana db.delete(TABLE_ACCOUNTS, ACCOUNTS_ID + "=" + accountId, null); 249afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana accountDeleted = true; 250afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana } 251afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana } 252afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana } finally { 253afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana cursor.close(); 254afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana if (accountDeleted) { 255afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana sendAccountsChangedBroadcast(); 256afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana } 257afa92b8f3d8f85fe2dde309f8f778926396539eaFred Quintana } 2583ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintana } 2593ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintana 2605ebbb4a6b3e16f711735ae0615b9a9ea64faad38Fred Quintana public void onServiceChanged(AuthenticatorDescription desc, boolean removed) { 2613ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintana boolean accountDeleted = false; 2623ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintana SQLiteDatabase db = mOpenHelper.getWritableDatabase(); 2633ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintana Cursor cursor = db.query(TABLE_ACCOUNTS, 2643ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintana new String[]{ACCOUNTS_ID, ACCOUNTS_TYPE, ACCOUNTS_NAME}, 2655ebbb4a6b3e16f711735ae0615b9a9ea64faad38Fred Quintana ACCOUNTS_TYPE + "=?", new String[]{desc.type}, null, null, null); 2663ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintana try { 2673ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintana while (cursor.moveToNext()) { 2683ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintana final long accountId = cursor.getLong(0); 2693ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintana final String accountType = cursor.getString(1); 2703ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintana final String accountName = cursor.getString(2); 2715ebbb4a6b3e16f711735ae0615b9a9ea64faad38Fred Quintana Log.d(TAG, "deleting account " + accountName + " because type " 2725ebbb4a6b3e16f711735ae0615b9a9ea64faad38Fred Quintana + accountType + " no longer has a registered authenticator"); 2735ebbb4a6b3e16f711735ae0615b9a9ea64faad38Fred Quintana db.delete(TABLE_ACCOUNTS, ACCOUNTS_ID + "=" + accountId, null); 2745ebbb4a6b3e16f711735ae0615b9a9ea64faad38Fred Quintana accountDeleted = true; 2753ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintana } 2763ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintana } finally { 2773ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintana cursor.close(); 2783ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintana if (accountDeleted) { 2793ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintana sendAccountsChangedBroadcast(); 2803ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintana } 2813ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintana } 282603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 283603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 284a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public String getPassword(Account account) { 285382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 286d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkAuthenticateAccountsPermission(account); 287d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 28826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 289603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana try { 290ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana return readPasswordFromDatabase(account); 291603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } finally { 29226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 293603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 294603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 295603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 296ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana private String readPasswordFromDatabase(Account account) { 29731957f1badbb900bbfe211317e1ea992d650a72dFred Quintana if (account == null) { 29831957f1badbb900bbfe211317e1ea992d650a72dFred Quintana return null; 29931957f1badbb900bbfe211317e1ea992d650a72dFred Quintana } 30031957f1badbb900bbfe211317e1ea992d650a72dFred Quintana 301ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana SQLiteDatabase db = mOpenHelper.getReadableDatabase(); 302ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana Cursor cursor = db.query(TABLE_ACCOUNTS, new String[]{ACCOUNTS_PASSWORD}, 303ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?", 304ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana new String[]{account.name, account.type}, null, null, null); 305ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana try { 306ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana if (cursor.moveToNext()) { 307ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana return cursor.getString(0); 308ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 309ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana return null; 310ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } finally { 311ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana cursor.close(); 312ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 313ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 314ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 315a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public String getUserData(Account account, String key) { 316382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 317382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (key == null) throw new IllegalArgumentException("key is null"); 318d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkAuthenticateAccountsPermission(account); 31926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 320603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana try { 321ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana return readUserDataFromDatabase(account, key); 322ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } finally { 323ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana restoreCallingIdentity(identityToken); 324ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 325ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 326ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 327ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana private String readUserDataFromDatabase(Account account, String key) { 32831957f1badbb900bbfe211317e1ea992d650a72dFred Quintana if (account == null) { 32931957f1badbb900bbfe211317e1ea992d650a72dFred Quintana return null; 33031957f1badbb900bbfe211317e1ea992d650a72dFred Quintana } 33131957f1badbb900bbfe211317e1ea992d650a72dFred Quintana 332ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana SQLiteDatabase db = mOpenHelper.getReadableDatabase(); 33386bd084cf683e9877b4146918192b3fe5e268cf5Fred Quintana Cursor cursor = db.query(TABLE_EXTRAS, new String[]{EXTRAS_VALUE}, 33486bd084cf683e9877b4146918192b3fe5e268cf5Fred Quintana EXTRAS_ACCOUNTS_ID 33586bd084cf683e9877b4146918192b3fe5e268cf5Fred Quintana + "=(select _id FROM accounts WHERE name=? AND type=?) AND " 33686bd084cf683e9877b4146918192b3fe5e268cf5Fred Quintana + EXTRAS_KEY + "=?", 33786bd084cf683e9877b4146918192b3fe5e268cf5Fred Quintana new String[]{account.name, account.type, key}, null, null, null); 338ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana try { 33986bd084cf683e9877b4146918192b3fe5e268cf5Fred Quintana if (cursor.moveToNext()) { 34086bd084cf683e9877b4146918192b3fe5e268cf5Fred Quintana return cursor.getString(0); 341603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 34286bd084cf683e9877b4146918192b3fe5e268cf5Fred Quintana return null; 343603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } finally { 34486bd084cf683e9877b4146918192b3fe5e268cf5Fred Quintana cursor.close(); 345603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 346603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 347603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 3489788976b1465ce982b5ae7c741345edd0ecd9322Fred Quintana public AuthenticatorDescription[] getAuthenticatorTypes() { 34926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 35026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 3519788976b1465ce982b5ae7c741345edd0ecd9322Fred Quintana Collection<AccountAuthenticatorCache.ServiceInfo<AuthenticatorDescription>> 3529788976b1465ce982b5ae7c741345edd0ecd9322Fred Quintana authenticatorCollection = mAuthenticatorCache.getAllServices(); 3539788976b1465ce982b5ae7c741345edd0ecd9322Fred Quintana AuthenticatorDescription[] types = 3549788976b1465ce982b5ae7c741345edd0ecd9322Fred Quintana new AuthenticatorDescription[authenticatorCollection.size()]; 35526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana int i = 0; 3569788976b1465ce982b5ae7c741345edd0ecd9322Fred Quintana for (AccountAuthenticatorCache.ServiceInfo<AuthenticatorDescription> authenticator 357718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana : authenticatorCollection) { 358718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana types[i] = authenticator.type; 35926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana i++; 36026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 36126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana return types; 36226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 36326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 364a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 365a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 366a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 367a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public Account[] getAccountsByType(String accountType) { 368ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana SQLiteDatabase db = mOpenHelper.getReadableDatabase(); 36926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana 370ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana final String selection = accountType == null ? null : (ACCOUNTS_TYPE + "=?"); 371ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana final String[] selectionArgs = accountType == null ? null : new String[]{accountType}; 372ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana Cursor cursor = db.query(TABLE_ACCOUNTS, ACCOUNT_NAME_TYPE_PROJECTION, 373ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana selection, selectionArgs, null, null, null); 374ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana try { 375ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana int i = 0; 376ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana Account[] accounts = new Account[cursor.getCount()]; 377ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana while (cursor.moveToNext()) { 378ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana accounts[i] = new Account(cursor.getString(1), cursor.getString(2)); 379ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana i++; 380603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 381ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana return accounts; 382603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } finally { 383ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana cursor.close(); 384603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 385603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 386603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 387a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public boolean addAccount(Account account, String password, Bundle extras) { 388382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 389d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkAuthenticateAccountsPermission(account); 390d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 391603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana // fails if the account already exists 39226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 393603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana try { 394ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana return insertAccountIntoDatabase(account, password, extras); 395ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } finally { 396ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana restoreCallingIdentity(identityToken); 397ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 398ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 399ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 400ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana private boolean insertAccountIntoDatabase(Account account, String password, Bundle extras) { 401ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana SQLiteDatabase db = mOpenHelper.getWritableDatabase(); 402ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana db.beginTransaction(); 403ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana try { 40431957f1badbb900bbfe211317e1ea992d650a72dFred Quintana if (account == null) { 40531957f1badbb900bbfe211317e1ea992d650a72dFred Quintana return false; 40631957f1badbb900bbfe211317e1ea992d650a72dFred Quintana } 40750c05f38b3728b7430dd4bb8d98565d9c5e56798Jim Miller boolean noBroadcast = false; 40850c05f38b3728b7430dd4bb8d98565d9c5e56798Jim Miller if (account.type.equals(GOOGLE_ACCOUNT_TYPE)) { 40950c05f38b3728b7430dd4bb8d98565d9c5e56798Jim Miller // Look for the 'nobroadcast' flag and remove it since we don't want it to persist 41050c05f38b3728b7430dd4bb8d98565d9c5e56798Jim Miller // in the db. 41150c05f38b3728b7430dd4bb8d98565d9c5e56798Jim Miller noBroadcast = extras.getBoolean(NO_BROADCAST_FLAG, false); 41250c05f38b3728b7430dd4bb8d98565d9c5e56798Jim Miller extras.remove(NO_BROADCAST_FLAG); 41350c05f38b3728b7430dd4bb8d98565d9c5e56798Jim Miller } 41450c05f38b3728b7430dd4bb8d98565d9c5e56798Jim Miller 415ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana long numMatches = DatabaseUtils.longForQuery(db, 416ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana "select count(*) from " + TABLE_ACCOUNTS 417ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana + " WHERE " + ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?", 418ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana new String[]{account.name, account.type}); 419ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana if (numMatches > 0) { 420ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana return false; 421ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 422ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana ContentValues values = new ContentValues(); 423ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana values.put(ACCOUNTS_NAME, account.name); 424ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana values.put(ACCOUNTS_TYPE, account.type); 425ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana values.put(ACCOUNTS_PASSWORD, password); 426ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana long accountId = db.insert(TABLE_ACCOUNTS, ACCOUNTS_NAME, values); 427ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana if (accountId < 0) { 428ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana return false; 429ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 430ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana if (extras != null) { 431ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana for (String key : extras.keySet()) { 432ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana final String value = extras.getString(key); 433ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana if (insertExtra(db, accountId, key, value) < 0) { 434ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana return false; 435603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 436603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 437603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 438ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana db.setTransactionSuccessful(); 43950c05f38b3728b7430dd4bb8d98565d9c5e56798Jim Miller if (!noBroadcast) { 44050c05f38b3728b7430dd4bb8d98565d9c5e56798Jim Miller sendAccountsChangedBroadcast(); 44150c05f38b3728b7430dd4bb8d98565d9c5e56798Jim Miller } 442ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana return true; 443603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } finally { 444ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana db.endTransaction(); 445603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 446603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 447603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 448603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private long insertExtra(SQLiteDatabase db, long accountId, String key, String value) { 449603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana ContentValues values = new ContentValues(); 450603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana values.put(EXTRAS_KEY, key); 451603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana values.put(EXTRAS_ACCOUNTS_ID, accountId); 452603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana values.put(EXTRAS_VALUE, value); 453603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana return db.insert(TABLE_EXTRAS, EXTRAS_KEY, values); 454603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 455603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 4563084a6f80180506ce26fe4773d9a19f004b7f625Fred Quintana public void hasFeatures(IAccountManagerResponse response, 457bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana Account account, String[] features) { 458382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (response == null) throw new IllegalArgumentException("response is null"); 459382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 460382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (features == null) throw new IllegalArgumentException("features is null"); 461bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana checkReadAccountsPermission(); 462bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana long identityToken = clearCallingIdentity(); 463bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana try { 464bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana new TestFeaturesSession(response, account, features).bind(); 465bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } finally { 466bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana restoreCallingIdentity(identityToken); 467bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 468bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 469bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana 470bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana private class TestFeaturesSession extends Session { 471bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana private final String[] mFeatures; 472bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana private final Account mAccount; 473bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana 474bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana public TestFeaturesSession(IAccountManagerResponse response, 475bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana Account account, String[] features) { 4768570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana super(response, account.type, false /* expectActivityLaunch */, 4778570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana true /* stripAuthTokenFromResult */); 478bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana mFeatures = features; 479bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana mAccount = account; 480bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 481bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana 482bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana public void run() throws RemoteException { 483bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana try { 484bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana mAuthenticator.hasFeatures(this, mAccount, mFeatures); 485bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } catch (RemoteException e) { 486bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana onError(AccountManager.ERROR_CODE_REMOTE_EXCEPTION, "remote exception"); 487bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 488bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 489bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana 490bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana public void onResult(Bundle result) { 491bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana IAccountManagerResponse response = getResponseAndClose(); 492bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana if (response != null) { 493bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana try { 494bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana if (result == null) { 495bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana onError(AccountManager.ERROR_CODE_INVALID_RESPONSE, "null bundle"); 496bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana return; 497bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 498bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana final Bundle newResult = new Bundle(); 499bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana newResult.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, 500bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT, false)); 501bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana response.onResult(newResult); 502bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } catch (RemoteException e) { 503bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana // if the caller is dead then there is no one to care about remote exceptions 504bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 505bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana Log.v(TAG, "failure while notifying response", e); 506bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 507bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 508bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 509bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 510bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana 511bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana protected String toDebugString(long now) { 5123084a6f80180506ce26fe4773d9a19f004b7f625Fred Quintana return super.toDebugString(now) + ", hasFeatures" 513bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana + ", " + mAccount 514bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana + ", " + (mFeatures != null ? TextUtils.join(",", mFeatures) : null); 515bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 516bb68a4fc54231e147d91fe3668d1409ccfd81a45Fred Quintana } 517307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana 518ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana public void removeAccount(IAccountManagerResponse response, Account account) { 519382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (response == null) throw new IllegalArgumentException("response is null"); 520382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 521d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkManageAccountsPermission(); 52226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 52326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 524ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana new RemoveAccountSession(response, account).bind(); 52526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 52626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 527a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 528603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 529603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 530ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana private class RemoveAccountSession extends Session { 531ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana final Account mAccount; 532ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana public RemoveAccountSession(IAccountManagerResponse response, Account account) { 5338570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana super(response, account.type, false /* expectActivityLaunch */, 5348570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana true /* stripAuthTokenFromResult */); 535ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana mAccount = account; 536ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 537ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 538ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana protected String toDebugString(long now) { 539ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana return super.toDebugString(now) + ", removeAccount" 540ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana + ", account " + mAccount; 541ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 542ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 543ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana public void run() throws RemoteException { 544ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana mAuthenticator.getAccountRemovalAllowed(this, mAccount); 545ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 546ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 547ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana public void onResult(Bundle result) { 548f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana if (result != null && result.containsKey(AccountManager.KEY_BOOLEAN_RESULT) 549f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana && !result.containsKey(AccountManager.KEY_INTENT)) { 550f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana final boolean removalAllowed = result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT); 551ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana if (removalAllowed) { 552ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana removeAccount(mAccount); 553ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 554ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana IAccountManagerResponse response = getResponseAndClose(); 555ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana if (response != null) { 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 569ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana private 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}); 573ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana sendAccountsChangedBroadcast(); 574ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 575ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 576a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void invalidateAuthToken(String accountType, String authToken) { 577382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (accountType == null) throw new IllegalArgumentException("accountType is null"); 578382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (authToken == null) throw new IllegalArgumentException("authToken is null"); 579b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana checkManageAccountsOrUseCredentialsPermissions(); 58026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 581603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana try { 58226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana SQLiteDatabase db = mOpenHelper.getWritableDatabase(); 58326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana db.beginTransaction(); 58426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 58526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana invalidateAuthToken(db, accountType, authToken); 58626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana db.setTransactionSuccessful(); 58726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 58826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana db.endTransaction(); 58926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 590603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } finally { 59126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 592603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 593603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 594603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 595603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private void invalidateAuthToken(SQLiteDatabase db, String accountType, String authToken) { 596ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana if (authToken == null || accountType == null) { 597ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana return; 598ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 5993326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana Cursor cursor = db.rawQuery( 6003326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana "SELECT " + TABLE_AUTHTOKENS + "." + AUTHTOKENS_ID 6013326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + ", " + TABLE_ACCOUNTS + "." + ACCOUNTS_NAME 6023326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + ", " + TABLE_AUTHTOKENS + "." + AUTHTOKENS_TYPE 6033326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + " FROM " + TABLE_ACCOUNTS 6043326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + " JOIN " + TABLE_AUTHTOKENS 6053326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + " ON " + TABLE_ACCOUNTS + "." + ACCOUNTS_ID 6063326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + " = " + AUTHTOKENS_ACCOUNTS_ID 6073326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + " WHERE " + AUTHTOKENS_AUTHTOKEN + " = ? AND " 6083326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + TABLE_ACCOUNTS + "." + ACCOUNTS_TYPE + " = ?", 6093326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana new String[]{authToken, accountType}); 6103326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana try { 6113326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana while (cursor.moveToNext()) { 6123326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana long authTokenId = cursor.getLong(0); 6133326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana String accountName = cursor.getString(1); 6143326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana String authTokenType = cursor.getString(2); 6153326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana db.delete(TABLE_AUTHTOKENS, AUTHTOKENS_ID + "=" + authTokenId, null); 616603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 6173326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } finally { 6183326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana cursor.close(); 619603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 620603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 621603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 622603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private boolean saveAuthTokenToDatabase(Account account, String type, String authToken) { 62331957f1badbb900bbfe211317e1ea992d650a72dFred Quintana if (account == null || type == null) { 62431957f1badbb900bbfe211317e1ea992d650a72dFred Quintana return false; 62531957f1badbb900bbfe211317e1ea992d650a72dFred Quintana } 6266dfd1382fe43592b9602fc6553e820c64067c759Fred Quintana cancelNotification(getSigninRequiredNotificationId(account)); 627603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana SQLiteDatabase db = mOpenHelper.getWritableDatabase(); 628603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana db.beginTransaction(); 629603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana try { 6303326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana long accountId = getAccountId(db, account); 6313326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana if (accountId < 0) { 6323326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana return false; 6333326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 6343326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana db.delete(TABLE_AUTHTOKENS, 6353326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana AUTHTOKENS_ACCOUNTS_ID + "=" + accountId + " AND " + AUTHTOKENS_TYPE + "=?", 6363326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana new String[]{type}); 6373326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana ContentValues values = new ContentValues(); 6383326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana values.put(AUTHTOKENS_ACCOUNTS_ID, accountId); 6393326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana values.put(AUTHTOKENS_TYPE, type); 6403326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana values.put(AUTHTOKENS_AUTHTOKEN, authToken); 6413326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana if (db.insert(TABLE_AUTHTOKENS, AUTHTOKENS_AUTHTOKEN, values) >= 0) { 642603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana db.setTransactionSuccessful(); 643603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana return true; 644603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 645603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana return false; 646603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } finally { 647603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana db.endTransaction(); 648603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 649603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 650603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 651603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public String readAuthTokenFromDatabase(Account account, String authTokenType) { 65231957f1badbb900bbfe211317e1ea992d650a72dFred Quintana if (account == null || authTokenType == null) { 65331957f1badbb900bbfe211317e1ea992d650a72dFred Quintana return null; 65431957f1badbb900bbfe211317e1ea992d650a72dFred Quintana } 655603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana SQLiteDatabase db = mOpenHelper.getReadableDatabase(); 65686bd084cf683e9877b4146918192b3fe5e268cf5Fred Quintana Cursor cursor = db.query(TABLE_AUTHTOKENS, new String[]{AUTHTOKENS_AUTHTOKEN}, 65786bd084cf683e9877b4146918192b3fe5e268cf5Fred Quintana AUTHTOKENS_ACCOUNTS_ID + "=(select _id FROM accounts WHERE name=? AND type=?) AND " 65886bd084cf683e9877b4146918192b3fe5e268cf5Fred Quintana + AUTHTOKENS_TYPE + "=?", 65986bd084cf683e9877b4146918192b3fe5e268cf5Fred Quintana new String[]{account.name, account.type, authTokenType}, 66086bd084cf683e9877b4146918192b3fe5e268cf5Fred Quintana null, null, null); 661603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana try { 66286bd084cf683e9877b4146918192b3fe5e268cf5Fred Quintana if (cursor.moveToNext()) { 66386bd084cf683e9877b4146918192b3fe5e268cf5Fred Quintana return cursor.getString(0); 664603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 66586bd084cf683e9877b4146918192b3fe5e268cf5Fred Quintana return null; 666603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } finally { 66786bd084cf683e9877b4146918192b3fe5e268cf5Fred Quintana cursor.close(); 668603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 669603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 670603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 671a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public String peekAuthToken(Account account, String authTokenType) { 672382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 673382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null"); 674d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkAuthenticateAccountsPermission(account); 67526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 67626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 6773326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana return readAuthTokenFromDatabase(account, authTokenType); 67826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 67926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 680603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 681603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 682603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 683a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void setAuthToken(Account account, String authTokenType, String authToken) { 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) { 696382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 697d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkAuthenticateAccountsPermission(account); 69826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 69926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 7003ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintana setPasswordInDB(account, password); 70126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 70226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 70326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 704603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 705603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 7063ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintana private void setPasswordInDB(Account account, String password) { 70731957f1badbb900bbfe211317e1ea992d650a72dFred Quintana if (account == null) { 70831957f1badbb900bbfe211317e1ea992d650a72dFred Quintana return; 70931957f1badbb900bbfe211317e1ea992d650a72dFred Quintana } 710d4a9d6c42bb412e27a8383aaacd051419d98a662Fred Quintana SQLiteDatabase db = mOpenHelper.getWritableDatabase(); 711d4a9d6c42bb412e27a8383aaacd051419d98a662Fred Quintana db.beginTransaction(); 712d4a9d6c42bb412e27a8383aaacd051419d98a662Fred Quintana try { 713d4a9d6c42bb412e27a8383aaacd051419d98a662Fred Quintana final ContentValues values = new ContentValues(); 714d4a9d6c42bb412e27a8383aaacd051419d98a662Fred Quintana values.put(ACCOUNTS_PASSWORD, password); 715d4a9d6c42bb412e27a8383aaacd051419d98a662Fred Quintana final long accountId = getAccountId(db, account); 716d4a9d6c42bb412e27a8383aaacd051419d98a662Fred Quintana if (accountId >= 0) { 717d4a9d6c42bb412e27a8383aaacd051419d98a662Fred Quintana final String[] argsAccountId = {String.valueOf(accountId)}; 718d4a9d6c42bb412e27a8383aaacd051419d98a662Fred Quintana db.update(TABLE_ACCOUNTS, values, ACCOUNTS_ID + "=?", argsAccountId); 719d4a9d6c42bb412e27a8383aaacd051419d98a662Fred Quintana db.delete(TABLE_AUTHTOKENS, AUTHTOKENS_ACCOUNTS_ID + "=?", argsAccountId); 720d4a9d6c42bb412e27a8383aaacd051419d98a662Fred Quintana db.setTransactionSuccessful(); 721d4a9d6c42bb412e27a8383aaacd051419d98a662Fred Quintana } 722d4a9d6c42bb412e27a8383aaacd051419d98a662Fred Quintana } finally { 723d4a9d6c42bb412e27a8383aaacd051419d98a662Fred Quintana db.endTransaction(); 724d4a9d6c42bb412e27a8383aaacd051419d98a662Fred Quintana } 7253ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintana sendAccountsChangedBroadcast(); 7263ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintana } 7273ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintana 7283326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana private void sendAccountsChangedBroadcast() { 7293326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana mContext.sendBroadcast(ACCOUNTS_CHANGED_INTENT); 7303326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 7313326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 732a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void clearPassword(Account account) { 733382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 734d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkManageAccountsPermission(); 73526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 73626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 7373ecd5f437580e49d80beecd29489d5fb1f7a7db0Fred Quintana setPasswordInDB(account, null); 73826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 73926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 74026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 741603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 742603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 743a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void setUserData(Account account, String key, String value) { 744382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (key == null) throw new IllegalArgumentException("key is null"); 745382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 746d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkAuthenticateAccountsPermission(account); 74726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 74831957f1badbb900bbfe211317e1ea992d650a72dFred Quintana if (account == null) { 74931957f1badbb900bbfe211317e1ea992d650a72dFred Quintana return; 75031957f1badbb900bbfe211317e1ea992d650a72dFred Quintana } 75150c05f38b3728b7430dd4bb8d98565d9c5e56798Jim Miller if (account.type.equals(GOOGLE_ACCOUNT_TYPE) && key.equals("broadcast")) { 75250c05f38b3728b7430dd4bb8d98565d9c5e56798Jim Miller sendAccountsChangedBroadcast(); 75350c05f38b3728b7430dd4bb8d98565d9c5e56798Jim Miller return; 75450c05f38b3728b7430dd4bb8d98565d9c5e56798Jim Miller } 755603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana try { 756ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana writeUserdataIntoDatabase(account, key, value); 757ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } finally { 758ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana restoreCallingIdentity(identityToken); 759ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 760ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 761ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 762ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana private void writeUserdataIntoDatabase(Account account, String key, String value) { 76331957f1badbb900bbfe211317e1ea992d650a72dFred Quintana if (account == null || key == null) { 76431957f1badbb900bbfe211317e1ea992d650a72dFred Quintana return; 76531957f1badbb900bbfe211317e1ea992d650a72dFred Quintana } 766ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana SQLiteDatabase db = mOpenHelper.getWritableDatabase(); 767ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana db.beginTransaction(); 768ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana try { 769ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana long accountId = getAccountId(db, account); 770ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana if (accountId < 0) { 771ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana return; 772ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 773ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana long extrasId = getExtrasId(db, accountId, key); 774ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana if (extrasId < 0 ) { 775ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana extrasId = insertExtra(db, accountId, key, value); 776ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana if (extrasId < 0) { 777603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana return; 778603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 779ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } else { 780ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana ContentValues values = new ContentValues(); 781ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana values.put(EXTRAS_VALUE, value); 782ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana if (1 != db.update(TABLE_EXTRAS, values, EXTRAS_ID + "=" + extrasId, null)) { 783ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana return; 78426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 785ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 786603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 787ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana db.setTransactionSuccessful(); 788603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } finally { 789ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana db.endTransaction(); 790603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 791603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 792603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 793d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private void onResult(IAccountManagerResponse response, Bundle result) { 794d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana try { 795d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana response.onResult(result); 796d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } catch (RemoteException e) { 797d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana // if the caller is dead then there is no one to care about remote 798d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana // exceptions 799d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 800d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Log.v(TAG, "failure while notifying response", e); 801d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 802d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 803d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 804d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 805a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void getAuthToken(IAccountManagerResponse response, final Account account, 806a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana final String authTokenType, final boolean notifyOnAuthFailure, 807a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana final boolean expectActivityLaunch, final Bundle loginOptions) { 808382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (response == null) throw new IllegalArgumentException("response is null"); 809382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 810382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null"); 811d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkBinderPermission(Manifest.permission.USE_CREDENTIALS); 812d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana final int callerUid = Binder.getCallingUid(); 813d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana final boolean permissionGranted = permissionIsGranted(account, authTokenType, callerUid); 814d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 81526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 81626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 817d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana // if the caller has permission, do the peek. otherwise go the more expensive 818d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana // route of starting a Session 819d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (permissionGranted) { 820d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana String authToken = readAuthTokenFromDatabase(account, authTokenType); 821d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (authToken != null) { 82226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana Bundle result = new Bundle(); 823f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana result.putString(AccountManager.KEY_AUTHTOKEN, authToken); 824f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name); 825f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana result.putString(AccountManager.KEY_ACCOUNT_TYPE, account.type); 826d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana onResult(response, result); 827d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana return; 828a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 829a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 830603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 8318570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana new Session(response, account.type, expectActivityLaunch, 8328570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana false /* stripAuthTokenFromResult */) { 83326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana protected String toDebugString(long now) { 83426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana if (loginOptions != null) loginOptions.keySet(); 83526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana return super.toDebugString(now) + ", getAuthToken" 83626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana + ", " + account 83726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana + ", authTokenType " + authTokenType 83826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana + ", loginOptions " + loginOptions 83926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana + ", notifyOnAuthFailure " + notifyOnAuthFailure; 84026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 841a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 84226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana public void run() throws RemoteException { 843d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana // If the caller doesn't have permission then create and return the 844d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana // "grant permission" intent instead of the "getAuthToken" intent. 845d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (!permissionGranted) { 846d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana mAuthenticator.getAuthTokenLabel(this, authTokenType); 847d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } else { 848d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana mAuthenticator.getAuthToken(this, account, authTokenType, loginOptions); 849d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 85026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 851a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 85226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana public void onResult(Bundle result) { 85326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana if (result != null) { 854f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana if (result.containsKey(AccountManager.KEY_AUTH_TOKEN_LABEL)) { 855d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Intent intent = newGrantCredentialsPermissionIntent(account, callerUid, 856d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana new AccountAuthenticatorResponse(this), 857d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana authTokenType, 858f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana result.getString(AccountManager.KEY_AUTH_TOKEN_LABEL)); 859d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Bundle bundle = new Bundle(); 860f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana bundle.putParcelable(AccountManager.KEY_INTENT, intent); 861d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana onResult(bundle); 862d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana return; 863d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 864f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana String authToken = result.getString(AccountManager.KEY_AUTHTOKEN); 86526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana if (authToken != null) { 866f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana String name = result.getString(AccountManager.KEY_ACCOUNT_NAME); 867f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana String type = result.getString(AccountManager.KEY_ACCOUNT_TYPE); 86826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana if (TextUtils.isEmpty(type) || TextUtils.isEmpty(name)) { 869f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana onError(AccountManager.ERROR_CODE_INVALID_RESPONSE, 87026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana "the type and name should not be empty"); 87126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana return; 87226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 8736dfd1382fe43592b9602fc6553e820c64067c759Fred Quintana saveAuthTokenToDatabase(new Account(name, type), 8746dfd1382fe43592b9602fc6553e820c64067c759Fred Quintana authTokenType, authToken); 875a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 876603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 877f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana Intent intent = result.getParcelable(AccountManager.KEY_INTENT); 87826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana if (intent != null && notifyOnAuthFailure) { 879d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana doNotification( 880f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana account, result.getString(AccountManager.KEY_AUTH_FAILED_MESSAGE), 88126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana intent); 88226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 883a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 88426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana super.onResult(result); 885a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 88626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana }.bind(); 88726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 88826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 88926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 890603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 891603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 892d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private void createNoCredentialsPermissionNotification(Account account, Intent intent) { 893d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana int uid = intent.getIntExtra( 894d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana GrantCredentialsPermissionActivity.EXTRAS_REQUESTING_UID, -1); 895d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana String authTokenType = intent.getStringExtra( 896d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana GrantCredentialsPermissionActivity.EXTRAS_AUTH_TOKEN_TYPE); 897d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana String authTokenLabel = intent.getStringExtra( 898d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana GrantCredentialsPermissionActivity.EXTRAS_AUTH_TOKEN_LABEL); 899d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 900d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Notification n = new Notification(android.R.drawable.stat_sys_warning, null, 901d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 0 /* when */); 902ee452ee5359cdfa3c3fbf6783722d3aaa2ec5ca6Eric Fischer final String titleAndSubtitle = 903ee452ee5359cdfa3c3fbf6783722d3aaa2ec5ca6Eric Fischer mContext.getString(R.string.permission_request_notification_with_subtitle, 904ee452ee5359cdfa3c3fbf6783722d3aaa2ec5ca6Eric Fischer account.name); 905ee452ee5359cdfa3c3fbf6783722d3aaa2ec5ca6Eric Fischer final int index = titleAndSubtitle.indexOf('\n'); 906ee452ee5359cdfa3c3fbf6783722d3aaa2ec5ca6Eric Fischer final String title = titleAndSubtitle.substring(0, index); 907ee452ee5359cdfa3c3fbf6783722d3aaa2ec5ca6Eric Fischer final String subtitle = titleAndSubtitle.substring(index + 1); 908d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana n.setLatestEventInfo(mContext, 909ee452ee5359cdfa3c3fbf6783722d3aaa2ec5ca6Eric Fischer title, subtitle, 910d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana PendingIntent.getActivity(mContext, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT)); 911d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana ((NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE)) 912d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana .notify(getCredentialPermissionNotificationId(account, authTokenType, uid), n); 913d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 914d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 915d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private Intent newGrantCredentialsPermissionIntent(Account account, int uid, 916d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana AccountAuthenticatorResponse response, String authTokenType, String authTokenLabel) { 917d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana RegisteredServicesCache.ServiceInfo<AuthenticatorDescription> serviceInfo = 918d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana mAuthenticatorCache.getServiceInfo( 919ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana AuthenticatorDescription.newKey(account.type)); 920d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (serviceInfo == null) { 921ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana throw new IllegalArgumentException("unknown account type: " + account.type); 922d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 923d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 924d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana final Context authContext; 925d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana try { 926d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana authContext = mContext.createPackageContext( 927d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana serviceInfo.type.packageName, 0); 928d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } catch (PackageManager.NameNotFoundException e) { 929ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana throw new IllegalArgumentException("unknown account type: " + account.type); 930d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 931d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 932d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Intent intent = new Intent(mContext, GrantCredentialsPermissionActivity.class); 933d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 934d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana intent.addCategory( 935d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana String.valueOf(getCredentialPermissionNotificationId(account, authTokenType, uid))); 936d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana intent.putExtra(GrantCredentialsPermissionActivity.EXTRAS_ACCOUNT, account); 937d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana intent.putExtra(GrantCredentialsPermissionActivity.EXTRAS_AUTH_TOKEN_LABEL, authTokenLabel); 938d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana intent.putExtra(GrantCredentialsPermissionActivity.EXTRAS_AUTH_TOKEN_TYPE, authTokenType); 939d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana intent.putExtra(GrantCredentialsPermissionActivity.EXTRAS_RESPONSE, response); 940d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana intent.putExtra(GrantCredentialsPermissionActivity.EXTRAS_ACCOUNT_TYPE_LABEL, 941d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana authContext.getString(serviceInfo.type.labelId)); 942d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana intent.putExtra(GrantCredentialsPermissionActivity.EXTRAS_PACKAGES, 943d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana mContext.getPackageManager().getPackagesForUid(uid)); 944d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana intent.putExtra(GrantCredentialsPermissionActivity.EXTRAS_REQUESTING_UID, uid); 945d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana return intent; 946d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 947d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 948d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private Integer getCredentialPermissionNotificationId(Account account, String authTokenType, 949d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana int uid) { 950d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Integer id; 951d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana synchronized(mCredentialsPermissionNotificationIds) { 952d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana final Pair<Pair<Account, String>, Integer> key = 953d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana new Pair<Pair<Account, String>, Integer>( 954d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana new Pair<Account, String>(account, authTokenType), uid); 955d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana id = mCredentialsPermissionNotificationIds.get(key); 956d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (id == null) { 957d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana id = mNotificationIds.incrementAndGet(); 958d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana mCredentialsPermissionNotificationIds.put(key, id); 959d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 960d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 961d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana return id; 962d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 963d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 964d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private Integer getSigninRequiredNotificationId(Account account) { 965d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Integer id; 966d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana synchronized(mSigninRequiredNotificationIds) { 967d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana id = mSigninRequiredNotificationIds.get(account); 968d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (id == null) { 969d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana id = mNotificationIds.incrementAndGet(); 970d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana mSigninRequiredNotificationIds.put(account, id); 971d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 972d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 973d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana return id; 974d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 975d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 976a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 9773326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana public void addAcount(final IAccountManagerResponse response, final String accountType, 9783326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana final String authTokenType, final String[] requiredFeatures, 979a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana final boolean expectActivityLaunch, final Bundle options) { 980382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (response == null) throw new IllegalArgumentException("response is null"); 981382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (accountType == null) throw new IllegalArgumentException("accountType is null"); 982d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkManageAccountsPermission(); 98326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 98426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 9858570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana new Session(response, accountType, expectActivityLaunch, 9868570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana true /* stripAuthTokenFromResult */) { 98726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana public void run() throws RemoteException { 9883348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache mAuthenticator.addAccount(this, mAccountType, authTokenType, requiredFeatures, 9893326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana options); 99026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 991a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 99226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana protected String toDebugString(long now) { 99326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana return super.toDebugString(now) + ", addAccount" 9943326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + ", accountType " + accountType 9953326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + ", requiredFeatures " 9963326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + (requiredFeatures != null 9973326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana ? TextUtils.join(",", requiredFeatures) 9983326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana : null); 99926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 100026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana }.bind(); 100126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 100226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 100326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1004603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1005603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1006a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void confirmCredentials(IAccountManagerResponse response, 1007f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana final Account account, final Bundle options, final boolean expectActivityLaunch) { 1008382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (response == null) throw new IllegalArgumentException("response is null"); 1009382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 1010d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkManageAccountsPermission(); 101126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 101226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 10138570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana new Session(response, account.type, expectActivityLaunch, 10148570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana true /* stripAuthTokenFromResult */) { 101526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana public void run() throws RemoteException { 1016f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana mAuthenticator.confirmCredentials(this, account, options); 101726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 101826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana protected String toDebugString(long now) { 101926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana return super.toDebugString(now) + ", confirmCredentials" 102026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana + ", " + account; 102126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 102226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana }.bind(); 102326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 102426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 102526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1026603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1027603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1028a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void updateCredentials(IAccountManagerResponse response, final Account account, 1029a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana final String authTokenType, final boolean expectActivityLaunch, 1030a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana final Bundle loginOptions) { 1031382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (response == null) throw new IllegalArgumentException("response is null"); 1032382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null) throw new IllegalArgumentException("account is null"); 1033382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null"); 1034d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkManageAccountsPermission(); 103526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 103626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 10378570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana new Session(response, account.type, expectActivityLaunch, 10388570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana true /* stripAuthTokenFromResult */) { 103926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana public void run() throws RemoteException { 104026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana mAuthenticator.updateCredentials(this, account, authTokenType, loginOptions); 104126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 104226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana protected String toDebugString(long now) { 104326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana if (loginOptions != null) loginOptions.keySet(); 104426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana return super.toDebugString(now) + ", updateCredentials" 104526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana + ", " + account 104626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana + ", authTokenType " + authTokenType 104726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana + ", loginOptions " + loginOptions; 104826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 104926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana }.bind(); 105026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 105126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 105226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1053603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1054603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1055a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void editProperties(IAccountManagerResponse response, final String accountType, 1056a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana final boolean expectActivityLaunch) { 1057382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (response == null) throw new IllegalArgumentException("response is null"); 1058382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (accountType == null) throw new IllegalArgumentException("accountType is null"); 1059d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkManageAccountsPermission(); 106026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 106126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 10628570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana new Session(response, accountType, expectActivityLaunch, 10638570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana true /* stripAuthTokenFromResult */) { 106426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana public void run() throws RemoteException { 106526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana mAuthenticator.editProperties(this, mAccountType); 106626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 106726fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana protected String toDebugString(long now) { 106826fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana return super.toDebugString(now) + ", editProperties" 106926fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana + ", accountType " + accountType; 107026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 107126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana }.bind(); 107226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 107326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 107426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1075603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1076603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 10773326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana private class GetAccountsByTypeAndFeatureSession extends Session { 10783326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana private final String[] mFeatures; 10793326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana private volatile Account[] mAccountsOfType = null; 10803326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana private volatile ArrayList<Account> mAccountsWithFeatures = null; 10813326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana private volatile int mCurrentAccount = 0; 10823326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 10833326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana public GetAccountsByTypeAndFeatureSession(IAccountManagerResponse response, 10843326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana String type, String[] features) { 10858570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana super(response, type, false /* expectActivityLaunch */, 10868570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana true /* stripAuthTokenFromResult */); 10873326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana mFeatures = features; 10883326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 10893326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 10903326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana public void run() throws RemoteException { 10913326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana mAccountsOfType = getAccountsByType(mAccountType); 10923326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana // check whether each account matches the requested features 10933326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana mAccountsWithFeatures = new ArrayList<Account>(mAccountsOfType.length); 10943326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana mCurrentAccount = 0; 10953326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 10963326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana checkAccount(); 10973326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 10983326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 10993326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana public void checkAccount() { 11003326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana if (mCurrentAccount >= mAccountsOfType.length) { 11013326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana sendResult(); 11023326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana return; 11033326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 11043326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 110529e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana final IAccountAuthenticator accountAuthenticator = mAuthenticator; 110629e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana if (accountAuthenticator == null) { 110729e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana // It is possible that the authenticator has died, which is indicated by 110829e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana // mAuthenticator being set to null. If this happens then just abort. 110929e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana // There is no need to send back a result or error in this case since 111029e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana // that already happened when mAuthenticator was cleared. 111129e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 111229e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana Log.v(TAG, "checkAccount: aborting session since we are no longer" 111329e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana + " connected to the authenticator, " + toDebugString()); 111429e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana } 111529e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana return; 111629e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana } 11173326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana try { 111829e94b81c7e145a5cb21f8c862e8d05b077b3548Fred Quintana accountAuthenticator.hasFeatures(this, mAccountsOfType[mCurrentAccount], mFeatures); 11193326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } catch (RemoteException e) { 1120f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana onError(AccountManager.ERROR_CODE_REMOTE_EXCEPTION, "remote exception"); 1121a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1122603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1123603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 11243326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana public void onResult(Bundle result) { 11253326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana mNumResults++; 11263326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana if (result == null) { 1127f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana onError(AccountManager.ERROR_CODE_INVALID_RESPONSE, "null bundle"); 11283326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana return; 11293326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 1130f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana if (result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT, false)) { 11313326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana mAccountsWithFeatures.add(mAccountsOfType[mCurrentAccount]); 11323326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 11333326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana mCurrentAccount++; 11343326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana checkAccount(); 1135a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 11363326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 11373326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana public void sendResult() { 11383326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana IAccountManagerResponse response = getResponseAndClose(); 11393326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana if (response != null) { 11403326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana try { 11413326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana Account[] accounts = new Account[mAccountsWithFeatures.size()]; 11423326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana for (int i = 0; i < accounts.length; i++) { 11433326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana accounts[i] = mAccountsWithFeatures.get(i); 11443326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 11453326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana Bundle result = new Bundle(); 1146f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana result.putParcelableArray(AccountManager.KEY_ACCOUNTS, accounts); 11473326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana response.onResult(result); 11483326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } catch (RemoteException e) { 11493326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana // if the caller is dead then there is no one to care about remote exceptions 11503326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 11513326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana Log.v(TAG, "failure while notifying response", e); 11523326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 11533326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 11543326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 11553326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 11563326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 11573326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 11583326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana protected String toDebugString(long now) { 11593326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana return super.toDebugString(now) + ", getAccountsByTypeAndFeatures" 11603326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana + ", " + (mFeatures != null ? TextUtils.join(",", mFeatures) : null); 11613326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 11623326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 1163ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 1164ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana public Account[] getAccounts(String type) { 1165ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana checkReadAccountsPermission(); 1166ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana long identityToken = clearCallingIdentity(); 1167ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana try { 1168ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana return getAccountsByType(type); 1169ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } finally { 1170ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana restoreCallingIdentity(identityToken); 1171ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 1172ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 1173ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana 1174ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana public void getAccountsByFeatures(IAccountManagerResponse response, 11753326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana String type, String[] features) { 1176382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (response == null) throw new IllegalArgumentException("response is null"); 1177382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (type == null) throw new IllegalArgumentException("accountType is null"); 1178d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkReadAccountsPermission(); 1179ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana if (features != null && type == null) { 11803326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana if (response != null) { 11813326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana try { 1182f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana response.onError(AccountManager.ERROR_CODE_BAD_ARGUMENTS, "type is null"); 11833326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } catch (RemoteException e) { 11843326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana // ignore this 11853326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 11863326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 11873326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana return; 11883326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 11893326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana long identityToken = clearCallingIdentity(); 11903326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana try { 1191ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana if (features == null || features.length == 0) { 1192d4a9d6c42bb412e27a8383aaacd051419d98a662Fred Quintana Account[] accounts = getAccountsByType(type); 1193d4a9d6c42bb412e27a8383aaacd051419d98a662Fred Quintana Bundle result = new Bundle(); 1194d4a9d6c42bb412e27a8383aaacd051419d98a662Fred Quintana result.putParcelableArray(AccountManager.KEY_ACCOUNTS, accounts); 1195d4a9d6c42bb412e27a8383aaacd051419d98a662Fred Quintana onResult(response, result); 1196ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana return; 1197ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana } 11983326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana new GetAccountsByTypeAndFeatureSession(response, type, features).bind(); 11993326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } finally { 12003326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana restoreCallingIdentity(identityToken); 12013326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 12023326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana } 12033326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana 1204603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private long getAccountId(SQLiteDatabase db, Account account) { 1205603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana Cursor cursor = db.query(TABLE_ACCOUNTS, new String[]{ACCOUNTS_ID}, 1206ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana "name=? AND type=?", new String[]{account.name, account.type}, null, null, null); 1207603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana try { 1208603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana if (cursor.moveToNext()) { 1209603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana return cursor.getLong(0); 1210603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1211603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana return -1; 1212603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } finally { 1213603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana cursor.close(); 1214603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1215603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1216603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1217603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private long getExtrasId(SQLiteDatabase db, long accountId, String key) { 1218603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana Cursor cursor = db.query(TABLE_EXTRAS, new String[]{EXTRAS_ID}, 1219603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana EXTRAS_ACCOUNTS_ID + "=" + accountId + " AND " + EXTRAS_KEY + "=?", 1220603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana new String[]{key}, null, null, null); 1221603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana try { 1222603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana if (cursor.moveToNext()) { 1223603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana return cursor.getLong(0); 1224603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1225603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana return -1; 1226603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } finally { 1227603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana cursor.close(); 1228603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1229603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1230603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1231a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana private abstract class Session extends IAccountAuthenticatorResponse.Stub 1232b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana implements IBinder.DeathRecipient, ServiceConnection { 1233603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana IAccountManagerResponse mResponse; 1234603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana final String mAccountType; 1235a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana final boolean mExpectActivityLaunch; 1236a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana final long mCreationTime; 1237a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 12383326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana public int mNumResults = 0; 1239a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana private int mNumRequestContinued = 0; 1240a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana private int mNumErrors = 0; 1241a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 1242603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1243603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana IAccountAuthenticator mAuthenticator = null; 1244603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 12458570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana private final boolean mStripAuthTokenFromResult; 12468570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana 1247a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public Session(IAccountManagerResponse response, String accountType, 12488570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana boolean expectActivityLaunch, boolean stripAuthTokenFromResult) { 1249603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana super(); 1250a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (response == null) throw new IllegalArgumentException("response is null"); 12513326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana if (accountType == null) throw new IllegalArgumentException("accountType is null"); 12528570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana mStripAuthTokenFromResult = stripAuthTokenFromResult; 1253603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mResponse = response; 1254603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mAccountType = accountType; 1255a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana mExpectActivityLaunch = expectActivityLaunch; 1256a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana mCreationTime = SystemClock.elapsedRealtime(); 1257a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana synchronized (mSessions) { 1258a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana mSessions.put(toString(), this); 1259a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1260a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana try { 1261a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana response.asBinder().linkToDeath(this, 0 /* flags */); 1262a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } catch (RemoteException e) { 1263a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana mResponse = null; 1264a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana binderDied(); 1265a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1266603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1267603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1268a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana IAccountManagerResponse getResponseAndClose() { 1269603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana if (mResponse == null) { 1270603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana // this session has already been closed 1271603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana return null; 1272603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1273a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana IAccountManagerResponse response = mResponse; 1274a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana close(); // this clears mResponse so we need to save the response before this call 1275a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana return response; 1276a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1277a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 1278a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana private void close() { 1279a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana synchronized (mSessions) { 1280a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (mSessions.remove(toString()) == null) { 1281a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana // the session was already closed, so bail out now 1282a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana return; 1283a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1284a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1285a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (mResponse != null) { 1286a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana // stop listening for response deaths 1287a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana mResponse.asBinder().unlinkToDeath(this, 0 /* flags */); 1288a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 1289a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana // clear this so that we don't accidentally send any further results 1290a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana mResponse = null; 1291a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1292603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana cancelTimeout(); 1293603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana unbind(); 1294a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1295a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 1296a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void binderDied() { 1297603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mResponse = null; 1298a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana close(); 1299a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1300a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 1301a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana protected String toDebugString() { 1302a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana return toDebugString(SystemClock.elapsedRealtime()); 1303a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1304a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 1305a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana protected String toDebugString(long now) { 1306a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana return "Session: expectLaunch " + mExpectActivityLaunch 1307a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + ", connected " + (mAuthenticator != null) 1308a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + ", stats (" + mNumResults + "/" + mNumRequestContinued 1309a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + "/" + mNumErrors + ")" 1310a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + ", lifetime " + ((now - mCreationTime) / 1000.0); 1311603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1312603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1313603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana void bind() { 1314a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 1315a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana Log.v(TAG, "initiating bind to authenticator type " + mAccountType); 1316a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1317b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana if (!bindToAuthenticator(mAccountType)) { 1318a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana Log.d(TAG, "bind attempt failed for " + toDebugString()); 1319f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana onError(AccountManager.ERROR_CODE_REMOTE_EXCEPTION, "bind failure"); 1320603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1321603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1322603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1323603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private void unbind() { 1324603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana if (mAuthenticator != null) { 1325603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mAuthenticator = null; 1326b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana mContext.unbindService(this); 1327603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1328603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1329603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1330603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public void scheduleTimeout() { 1331603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mMessageHandler.sendMessageDelayed( 1332603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mMessageHandler.obtainMessage(MESSAGE_TIMED_OUT, this), TIMEOUT_DELAY_MS); 1333603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1334603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1335603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public void cancelTimeout() { 1336603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mMessageHandler.removeMessages(MESSAGE_TIMED_OUT, this); 1337603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1338603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1339b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana public void onServiceConnected(ComponentName name, IBinder service) { 1340603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mAuthenticator = IAccountAuthenticator.Stub.asInterface(service); 1341a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana try { 1342a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana run(); 1343a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } catch (RemoteException e) { 1344f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana onError(AccountManager.ERROR_CODE_REMOTE_EXCEPTION, 1345a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana "remote exception"); 1346a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1347603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1348603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1349b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana public void onServiceDisconnected(ComponentName name) { 1350a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana mAuthenticator = null; 1351a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana IAccountManagerResponse response = getResponseAndClose(); 1352603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana if (response != null) { 1353f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana onError(AccountManager.ERROR_CODE_REMOTE_EXCEPTION, 1354a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana "disconnected"); 1355603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1356603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1357603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1358b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana public abstract void run() throws RemoteException; 1359b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana 1360603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public void onTimedOut() { 1361a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana IAccountManagerResponse response = getResponseAndClose(); 1362603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana if (response != null) { 1363f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana onError(AccountManager.ERROR_CODE_REMOTE_EXCEPTION, 1364a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana "timeout"); 1365603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1366603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1367603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1368a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void onResult(Bundle result) { 1369a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana mNumResults++; 1370f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana if (result != null && !TextUtils.isEmpty(result.getString(AccountManager.KEY_AUTHTOKEN))) { 1371f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana String accountName = result.getString(AccountManager.KEY_ACCOUNT_NAME); 1372f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana String accountType = result.getString(AccountManager.KEY_ACCOUNT_TYPE); 1373d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (!TextUtils.isEmpty(accountName) && !TextUtils.isEmpty(accountType)) { 1374d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Account account = new Account(accountName, accountType); 1375d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana cancelNotification(getSigninRequiredNotificationId(account)); 1376d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1377603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1378a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana IAccountManagerResponse response; 1379a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (mExpectActivityLaunch && result != null 1380f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana && result.containsKey(AccountManager.KEY_INTENT)) { 1381a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana response = mResponse; 1382a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } else { 1383a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana response = getResponseAndClose(); 1384603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1385603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana if (response != null) { 1386603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana try { 1387a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (result == null) { 1388f7ae77cd67f1a3993b8e56c1af4720a7adf4e69dFred Quintana response.onError(AccountManager.ERROR_CODE_INVALID_RESPONSE, 1389a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana "null bundle returned"); 1390a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } else { 13918570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana if (mStripAuthTokenFromResult) { 13928570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana result.remove(AccountManager.KEY_AUTHTOKEN); 13938570f7440780db5c9b410e033e843b0e80e2fd27Fred Quintana } 1394a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana response.onResult(result); 1395a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1396603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } catch (RemoteException e) { 1397a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana // if the caller is dead then there is no one to care about remote exceptions 1398a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 1399a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana Log.v(TAG, "failure while notifying response", e); 1400a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1401603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1402603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1403603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1404603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1405a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana public void onRequestContinued() { 1406a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana mNumRequestContinued++; 1407603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1408603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1409603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public void onError(int errorCode, String errorMessage) { 1410a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana mNumErrors++; 1411a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 1412a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana Log.v(TAG, "Session.onError: " + errorCode + ", " + errorMessage); 1413603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1414a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana IAccountManagerResponse response = getResponseAndClose(); 1415a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (response != null) { 1416a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 1417a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana Log.v(TAG, "Session.onError: responding"); 1418a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1419a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana try { 1420a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana response.onError(errorCode, errorMessage); 1421a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } catch (RemoteException e) { 1422a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 1423a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana Log.v(TAG, "Session.onError: caught RemoteException while responding", e); 1424a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1425a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1426a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } else { 1427a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 1428a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana Log.v(TAG, "Session.onError: already closed"); 1429a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1430603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1431603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1432b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana 1433b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana /** 1434b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana * find the component name for the authenticator and initiate a bind 1435b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana * if no authenticator or the bind fails then return false, otherwise return true 1436b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana */ 1437b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana private boolean bindToAuthenticator(String authenticatorType) { 1438b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana AccountAuthenticatorCache.ServiceInfo<AuthenticatorDescription> authenticatorInfo = 1439b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana mAuthenticatorCache.getServiceInfo( 1440b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana AuthenticatorDescription.newKey(authenticatorType)); 1441b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana if (authenticatorInfo == null) { 1442b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 1443b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana Log.v(TAG, "there is no authenticator for " + authenticatorType 1444b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana + ", bailing out"); 1445b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana } 1446b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana return false; 1447b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana } 1448b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana 1449b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana Intent intent = new Intent(); 1450b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana intent.setAction(AccountManager.ACTION_AUTHENTICATOR_INTENT); 1451b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana intent.setComponent(authenticatorInfo.componentName); 1452b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 1453b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana Log.v(TAG, "performing bindService to " + authenticatorInfo.componentName); 1454b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana } 1455b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana if (!mContext.bindService(intent, this, Context.BIND_AUTO_CREATE)) { 1456b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 1457b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana Log.v(TAG, "bindService to " + authenticatorInfo.componentName + " failed"); 1458b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana } 1459b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana return false; 1460b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana } 1461b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana 1462b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana 1463b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana return true; 1464b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana } 1465603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1466603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1467603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private class MessageHandler extends Handler { 1468603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana MessageHandler(Looper looper) { 1469603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana super(looper); 1470603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 14713348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache 1472603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public void handleMessage(Message msg) { 1473603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana switch (msg.what) { 1474603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana case MESSAGE_TIMED_OUT: 1475603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana Session session = (Session)msg.obj; 1476603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana session.onTimedOut(); 1477603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana break; 1478603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1479603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana default: 1480603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana throw new IllegalStateException("unhandled message: " + msg.what); 1481603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1482603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1483603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1484603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1485a8529f68671a8a118751cb6ad577f44eaf076b96Oscar Montemayor private static String getDatabaseName() { 14861f4df90bfab8ca42eabe95f19eadff3432eee7fdOscar Montemayor return DATABASE_NAME; 1487a8529f68671a8a118751cb6ad577f44eaf076b96Oscar Montemayor } 1488a8529f68671a8a118751cb6ad577f44eaf076b96Oscar Montemayor 1489603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private class DatabaseHelper extends SQLiteOpenHelper { 1490a8529f68671a8a118751cb6ad577f44eaf076b96Oscar Montemayor 1491603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public DatabaseHelper(Context context) { 1492a8529f68671a8a118751cb6ad577f44eaf076b96Oscar Montemayor super(context, AccountManagerService.getDatabaseName(), null, DATABASE_VERSION); 1493603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1494603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1495603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana @Override 1496603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public void onCreate(SQLiteDatabase db) { 1497603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana db.execSQL("CREATE TABLE " + TABLE_ACCOUNTS + " ( " 1498603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + ACCOUNTS_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " 1499603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + ACCOUNTS_NAME + " TEXT NOT NULL, " 1500603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + ACCOUNTS_TYPE + " TEXT NOT NULL, " 1501603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + ACCOUNTS_PASSWORD + " TEXT, " 1502603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + "UNIQUE(" + ACCOUNTS_NAME + "," + ACCOUNTS_TYPE + "))"); 1503603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1504603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana db.execSQL("CREATE TABLE " + TABLE_AUTHTOKENS + " ( " 1505603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + AUTHTOKENS_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " 1506603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + AUTHTOKENS_ACCOUNTS_ID + " INTEGER NOT NULL, " 1507603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + AUTHTOKENS_TYPE + " TEXT NOT NULL, " 1508603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + AUTHTOKENS_AUTHTOKEN + " TEXT, " 1509603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + "UNIQUE (" + AUTHTOKENS_ACCOUNTS_ID + "," + AUTHTOKENS_TYPE + "))"); 1510603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1511d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana createGrantsTable(db); 1512d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 1513603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana db.execSQL("CREATE TABLE " + TABLE_EXTRAS + " ( " 1514603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + EXTRAS_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " 1515603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + EXTRAS_ACCOUNTS_ID + " INTEGER, " 1516603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + EXTRAS_KEY + " TEXT NOT NULL, " 1517603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + EXTRAS_VALUE + " TEXT, " 1518603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + "UNIQUE(" + EXTRAS_ACCOUNTS_ID + "," + EXTRAS_KEY + "))"); 1519603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1520603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana db.execSQL("CREATE TABLE " + TABLE_META + " ( " 1521603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + META_KEY + " TEXT PRIMARY KEY NOT NULL, " 1522603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana + META_VALUE + " TEXT)"); 1523a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 1524d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana createAccountsDeletionTrigger(db); 1525d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1526d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 1527d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private void createAccountsDeletionTrigger(SQLiteDatabase db) { 1528a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana db.execSQL("" 1529a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + " CREATE TRIGGER " + TABLE_ACCOUNTS + "Delete DELETE ON " + TABLE_ACCOUNTS 1530a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + " BEGIN" 1531a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + " DELETE FROM " + TABLE_AUTHTOKENS 1532a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + " WHERE " + AUTHTOKENS_ACCOUNTS_ID + "=OLD." + ACCOUNTS_ID + " ;" 1533a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + " DELETE FROM " + TABLE_EXTRAS 1534a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + " WHERE " + EXTRAS_ACCOUNTS_ID + "=OLD." + ACCOUNTS_ID + " ;" 1535d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + " DELETE FROM " + TABLE_GRANTS 1536d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + " WHERE " + GRANTS_ACCOUNTS_ID + "=OLD." + ACCOUNTS_ID + " ;" 1537a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana + " END"); 1538603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1539603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1540d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private void createGrantsTable(SQLiteDatabase db) { 1541d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana db.execSQL("CREATE TABLE " + TABLE_GRANTS + " ( " 1542d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + GRANTS_ACCOUNTS_ID + " INTEGER NOT NULL, " 1543d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + GRANTS_AUTH_TOKEN_TYPE + " STRING NOT NULL, " 1544d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + GRANTS_GRANTEE_UID + " INTEGER NOT NULL, " 1545d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + "UNIQUE (" + GRANTS_ACCOUNTS_ID + "," + GRANTS_AUTH_TOKEN_TYPE 1546d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + "," + GRANTS_GRANTEE_UID + "))"); 1547d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1548d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 1549603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana @Override 1550603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 1551a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana Log.e(TAG, "upgrade from version " + oldVersion + " to version " + newVersion); 1552603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1553a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana if (oldVersion == 1) { 1554d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana // no longer need to do anything since the work is done 1555d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana // when upgrading from version 2 1556d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana oldVersion++; 1557d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1558d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 1559d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (oldVersion == 2) { 1560d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana createGrantsTable(db); 1561d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana db.execSQL("DROP TRIGGER " + TABLE_ACCOUNTS + "Delete"); 1562d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana createAccountsDeletionTrigger(db); 1563a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana oldVersion++; 1564a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 15653348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache 15663348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache if (oldVersion == 3) { 15673348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache db.execSQL("UPDATE " + TABLE_ACCOUNTS + " SET " + ACCOUNTS_TYPE + 15683348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache " = 'com.google' WHERE " + ACCOUNTS_TYPE + " == 'com.google.GAIA'"); 15693348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache oldVersion++; 15703348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache } 1571603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1572603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1573603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana @Override 1574603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public void onOpen(SQLiteDatabase db) { 1575603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "opened database " + DATABASE_NAME); 1576603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1577603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1578603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1579603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private void setMetaValue(String key, String value) { 1580603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana ContentValues values = new ContentValues(); 1581603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana values.put(META_KEY, key); 1582603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana values.put(META_VALUE, value); 1583603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mOpenHelper.getWritableDatabase().replace(TABLE_META, META_KEY, values); 1584603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1585603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1586603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private String getMetaValue(String key) { 1587603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana Cursor c = mOpenHelper.getReadableDatabase().query(TABLE_META, 1588603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana new String[]{META_VALUE}, META_KEY + "=?", new String[]{key}, null, null, null); 1589603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana try { 1590603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana if (c.moveToNext()) { 1591603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana return c.getString(0); 1592603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1593603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana return null; 1594603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } finally { 1595603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana c.close(); 1596603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1597603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1598603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1599603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana private class SimWatcher extends BroadcastReceiver { 1600603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public SimWatcher(Context context) { 1601603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana // Re-scan the SIM card when the SIM state changes, and also if 1602603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana // the disk recovers from a full state (we may have failed to handle 1603603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana // things properly while the disk was full). 1604603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana final IntentFilter filter = new IntentFilter(); 1605603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED); 1606603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana filter.addAction(Intent.ACTION_DEVICE_STORAGE_OK); 1607603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana context.registerReceiver(this, filter); 1608603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 16093348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache 1610603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana /** 1611603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * Compare the IMSI to the one stored in the login service's 1612603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * database. If they differ, erase all passwords and 1613603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * authtokens (and store the new IMSI). 1614603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana */ 1615603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana @Override 1616603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public void onReceive(Context context, Intent intent) { 1617885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker // Check IMSI on every update; nothing happens if the IMSI 1618885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker // is missing or unchanged. 1619885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker TelephonyManager telephonyManager = 1620885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); 1621885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker if (telephonyManager == null) { 1622885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker Log.w(TAG, "failed to get TelephonyManager"); 1623885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker return; 1624885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker } 1625885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker String imsi = telephonyManager.getSubscriberId(); 1626885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker 1627885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker // If the subscriber ID is an empty string, don't do anything. 1628603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana if (TextUtils.isEmpty(imsi)) return; 1629603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1630885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker // If the current IMSI matches what's stored, don't do anything. 1631603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana String storedImsi = getMetaValue("imsi"); 1632603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 1633603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana Log.v(TAG, "current IMSI=" + imsi + "; stored IMSI=" + storedImsi); 1634603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1635885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker if (imsi.equals(storedImsi)) return; 1636885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker 1637885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker // If a CDMA phone is unprovisioned, getSubscriberId() 1638885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker // will return a different value, but we *don't* erase the 1639885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker // passwords. We only erase them if it has a different 1640885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker // subscriber ID once it's provisioned. 1641885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker if (telephonyManager.getPhoneType() == TelephonyManager.PHONE_TYPE_CDMA) { 1642885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker IBinder service = ServiceManager.checkService(Context.TELEPHONY_SERVICE); 1643885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker if (service == null) { 1644885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker Log.w(TAG, "call to checkService(TELEPHONY_SERVICE) failed"); 1645885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker return; 1646885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker } 1647885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker ITelephony telephony = ITelephony.Stub.asInterface(service); 1648885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker if (telephony == null) { 1649885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker Log.w(TAG, "failed to get ITelephony interface"); 1650885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker return; 1651885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker } 1652885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker boolean needsProvisioning; 1653885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker try { 1654885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker needsProvisioning = telephony.getCdmaNeedsProvisioning(); 1655885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker } catch (RemoteException e) { 1656885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker Log.w(TAG, "exception while checking provisioning", e); 1657885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker // default to NOT wiping out the passwords 1658885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker needsProvisioning = true; 1659885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker } 1660885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker if (needsProvisioning) { 1661885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker // if the phone needs re-provisioning, don't do anything. 1662885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker if (Log.isLoggable(TAG, Log.VERBOSE)) { 1663885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker Log.v(TAG, "current IMSI=" + imsi + " (needs provisioning); stored IMSI=" + 1664885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker storedImsi); 1665885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker } 1666885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker return; 1667885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker } 1668885cfc23a42f2a4f8578e6a2182af4d9a0a78b1fDoug Zongker } 1669603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 16705b462477a90cd08551149fc649ff3035b5331d2djsh if (!imsi.equals(storedImsi) && !TextUtils.isEmpty(storedImsi)) { 167127844c386e5567a91ab781265ae5ad40d0ab1e27Jim Miller Log.w(TAG, "wiping all passwords and authtokens because IMSI changed (" 167227844c386e5567a91ab781265ae5ad40d0ab1e27Jim Miller + "stored=" + storedImsi + ", current=" + imsi + ")"); 1673603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana SQLiteDatabase db = mOpenHelper.getWritableDatabase(); 1674603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana db.beginTransaction(); 1675603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana try { 1676603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana db.execSQL("DELETE from " + TABLE_AUTHTOKENS); 1677603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana db.execSQL("UPDATE " + TABLE_ACCOUNTS + " SET " + ACCOUNTS_PASSWORD + " = ''"); 16783326920329cecb57c7ff1fc5c6add5c98aab9ed9Fred Quintana sendAccountsChangedBroadcast(); 1679603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana db.setTransactionSuccessful(); 1680603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } finally { 1681603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana db.endTransaction(); 1682603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1683603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1684603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana setMetaValue("imsi", imsi); 1685603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1686603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1687603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 1688603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana public IBinder onBind(Intent intent) { 1689603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana return asBinder(); 1690603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 1691a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 16921cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks /** 16931cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks * Searches array of arguments for the specified string 16941cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks * @param args array of argument strings 16951cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks * @param value value to search for 16961cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks * @return true if the value is contained in the array 16971cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks */ 16981cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks private static boolean scanArgs(String[] args, String value) { 16991cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks if (args != null) { 17001cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks for (String arg : args) { 17011cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks if (value.equals(arg)) { 17021cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks return true; 17031cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks } 1704a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1705a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 17061cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks return false; 17071cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks } 1708a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 17091cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) { 17101cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks final boolean isCheckinRequest = scanArgs(args, "--checkin") || scanArgs(args, "-c"); 17111cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks 17121cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks if (isCheckinRequest) { 17131cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks // This is a checkin request. *Only* upload the account types and the count of each. 17141cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks SQLiteDatabase db = mOpenHelper.getReadableDatabase(); 1715a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 17161cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks Cursor cursor = db.query(TABLE_ACCOUNTS, ACCOUNT_TYPE_COUNT_PROJECTION, 17171cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks null, null, ACCOUNTS_TYPE, null, null); 17181cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks try { 17191cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks while (cursor.moveToNext()) { 17201cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks // print type,count 17211cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks fout.println(cursor.getString(0) + "," + cursor.getString(1)); 17221cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks } 17231cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks } finally { 17241cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks if (cursor != null) { 17251cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks cursor.close(); 17261cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks } 17271cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks } 17281cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks } else { 1729c2e4691d788088b22eadc9b2d35e9bdf0b6a0ffcFred Quintana Account[] accounts = getAccountsByType(null /* type */); 1730307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana fout.println("Accounts: " + accounts.length); 1731307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana for (Account account : accounts) { 1732307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana fout.println(" " + account); 1733307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana } 1734307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana 1735307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana fout.println(); 17361cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks synchronized (mSessions) { 17371cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks final long now = SystemClock.elapsedRealtime(); 1738307da1a46b4c9b711bafe8fbaaa6b98e8868c18eFred Quintana fout.println("Active Sessions: " + mSessions.size()); 17391cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks for (Session session : mSessions.values()) { 17401cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks fout.println(" " + session.toDebugString(now)); 17411cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks } 17421cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks } 17431cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks 17441cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks fout.println(); 17451cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks mAuthenticatorCache.dump(fd, fout, args); 17461cd7d0e591b61a1e5d0be4073e9b9f976279cc84Jason Parks } 1747a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1748a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 1749d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private void doNotification(Account account, CharSequence message, Intent intent) { 175026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 175126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 175226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 175326fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana Log.v(TAG, "doNotification: " + message + " intent:" + intent); 175426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1755a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 1756d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (intent.getComponent() != null && 1757d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana GrantCredentialsPermissionActivity.class.getName().equals( 1758d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana intent.getComponent().getClassName())) { 1759d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana createNoCredentialsPermissionNotification(account, intent); 1760d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } else { 176133f889ae270f888f8fdc084f5f1f3d443532a46aFred Quintana final Integer notificationId = getSigninRequiredNotificationId(account); 176233f889ae270f888f8fdc084f5f1f3d443532a46aFred Quintana intent.addCategory(String.valueOf(notificationId)); 1763d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Notification n = new Notification(android.R.drawable.stat_sys_warning, null, 1764d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 0 /* when */); 176533f889ae270f888f8fdc084f5f1f3d443532a46aFred Quintana final String notificationTitleFormat = 176633f889ae270f888f8fdc084f5f1f3d443532a46aFred Quintana mContext.getText(R.string.notification_title).toString(); 176733f889ae270f888f8fdc084f5f1f3d443532a46aFred Quintana n.setLatestEventInfo(mContext, 176833f889ae270f888f8fdc084f5f1f3d443532a46aFred Quintana String.format(notificationTitleFormat, account.name), 1769d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana message, PendingIntent.getActivity( 1770d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana mContext, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT)); 1771d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana ((NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE)) 177233f889ae270f888f8fdc084f5f1f3d443532a46aFred Quintana .notify(notificationId, n); 1773d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 177426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 177526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 177626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1777a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1778a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana 1779d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private void cancelNotification(int id) { 178026fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana long identityToken = clearCallingIdentity(); 178126fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana try { 178226fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana ((NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE)) 1783d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana .cancel(id); 178426fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } finally { 178526fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana restoreCallingIdentity(identityToken); 178626fc5eba506bf29f7f5343e836484a43702c8deaFred Quintana } 1787a698f4276968d078b1b9e2f3738c4f559a3307b2Fred Quintana } 1788d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 1789b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana /** Succeeds if any of the specified permissions are granted. */ 1790b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana private void checkBinderPermission(String... permissions) { 1791d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana final int uid = Binder.getCallingUid(); 1792b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana 1793b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana for (String perm : permissions) { 1794b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana if (mContext.checkCallingOrSelfPermission(perm) == PackageManager.PERMISSION_GRANTED) { 1795b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 1796b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana Log.v(TAG, "caller uid " + uid + " has " + perm); 1797b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana } 1798b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana return; 1799b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana } 1800d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1801b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana 1802b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana String msg = "caller uid " + uid + " lacks any of " + TextUtils.join(",", permissions); 1803b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana Log.w(TAG, msg); 1804b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana throw new SecurityException(msg); 1805d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1806d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 18077be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana private boolean inSystemImage(int callerUid) { 18087be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana String[] packages = mContext.getPackageManager().getPackagesForUid(callerUid); 18097be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana for (String name : packages) { 18107be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana try { 18117be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana PackageInfo packageInfo = 18127be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana mContext.getPackageManager().getPackageInfo(name, 0 /* flags */); 18137be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana if ((packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 18147be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana return true; 18157be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana } 18167be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana } catch (PackageManager.NameNotFoundException e) { 18177be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana return false; 18187be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana } 18197be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana } 18207be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana return false; 18217be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana } 18227be5964e74978ebc7d5fd24562de5738d31cf009Fred Quintana 1823d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private boolean permissionIsGranted(Account account, String authTokenType, int callerUid) { 1824b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana final boolean inSystemImage = inSystemImage(callerUid); 182531957f1badbb900bbfe211317e1ea992d650a72dFred Quintana final boolean fromAuthenticator = account != null 182631957f1badbb900bbfe211317e1ea992d650a72dFred Quintana && hasAuthenticatorUid(account.type, callerUid); 182731957f1badbb900bbfe211317e1ea992d650a72dFred Quintana final boolean hasExplicitGrants = account != null 182831957f1badbb900bbfe211317e1ea992d650a72dFred Quintana && hasExplicitlyGrantedPermission(account, authTokenType); 1829d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 1830d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Log.v(TAG, "checkGrantsOrCallingUidAgainstAuthenticator: caller uid " 1831d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + callerUid + ", account " + account 1832d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + ": is authenticator? " + fromAuthenticator 1833d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + ", has explicit permission? " + hasExplicitGrants); 1834d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1835b839afc33ea4a7b549b6dd703e5c48858ce877d0Fred Quintana return fromAuthenticator || hasExplicitGrants || inSystemImage; 1836d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1837d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 18381a23191bbde11505d6e0c25c04a60b41cb27fd31Fred Quintana private boolean hasAuthenticatorUid(String accountType, int callingUid) { 1839d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana for (RegisteredServicesCache.ServiceInfo<AuthenticatorDescription> serviceInfo : 1840d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana mAuthenticatorCache.getAllServices()) { 1841d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (serviceInfo.type.type.equals(accountType)) { 1842ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana return (serviceInfo.uid == callingUid) || 1843ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana (mContext.getPackageManager().checkSignatures(serviceInfo.uid, callingUid) 1844ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana == PackageManager.SIGNATURE_MATCH); 1845d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1846d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1847d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana return false; 1848d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1849d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 1850d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private boolean hasExplicitlyGrantedPermission(Account account, String authTokenType) { 1851d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (Binder.getCallingUid() == android.os.Process.SYSTEM_UID) { 1852d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana return true; 1853d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1854d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana SQLiteDatabase db = mOpenHelper.getReadableDatabase(); 1855d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana String[] args = {String.valueOf(Binder.getCallingUid()), authTokenType, 1856ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana account.name, account.type}; 1857d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana final boolean permissionGranted = 1858d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana DatabaseUtils.longForQuery(db, COUNT_OF_MATCHING_GRANTS, args) != 0; 1859d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (!permissionGranted && isDebuggableMonkeyBuild) { 1860d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana // TODO: Skip this check when running automated tests. Replace this 1861d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana // with a more general solution. 1862751fdc09bb7ab0ce6feac7b7a823e38ed858feb0Fred Quintana Log.d(TAG, "no credentials permission for usage of " + account + ", " 1863d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + authTokenType + " by uid " + Binder.getCallingUid() 1864d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + " but ignoring since this is a monkey build"); 1865d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana return true; 1866d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1867d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana return permissionGranted; 1868d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1869d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 1870d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private void checkCallingUidAgainstAuthenticator(Account account) { 1871d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana final int uid = Binder.getCallingUid(); 187231957f1badbb900bbfe211317e1ea992d650a72dFred Quintana if (account == null || !hasAuthenticatorUid(account.type, uid)) { 1873d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana String msg = "caller uid " + uid + " is different than the authenticator's uid"; 1874d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Log.w(TAG, msg); 1875d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana throw new SecurityException(msg); 1876d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1877d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (Log.isLoggable(TAG, Log.VERBOSE)) { 1878d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana Log.v(TAG, "caller uid " + uid + " is the same as the authenticator's uid"); 1879d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1880d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1881d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 1882d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private void checkAuthenticateAccountsPermission(Account account) { 1883d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkBinderPermission(Manifest.permission.AUTHENTICATE_ACCOUNTS); 1884d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkCallingUidAgainstAuthenticator(account); 1885d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1886d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 1887d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private void checkReadAccountsPermission() { 1888d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkBinderPermission(Manifest.permission.GET_ACCOUNTS); 1889d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1890d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 1891d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana private void checkManageAccountsPermission() { 1892d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana checkBinderPermission(Manifest.permission.MANAGE_ACCOUNTS); 1893d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1894d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 1895b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana private void checkManageAccountsOrUseCredentialsPermissions() { 1896b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana checkBinderPermission(Manifest.permission.MANAGE_ACCOUNTS, 1897b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana Manifest.permission.USE_CREDENTIALS); 1898b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana } 1899b38eb14dbf58c8230f5b54c481b85587d9ef7c78Fred Quintana 1900d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana /** 1901d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * Allow callers with the given uid permission to get credentials for account/authTokenType. 1902d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * <p> 1903d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * Although this is public it can only be accessed via the AccountManagerService object 1904d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * which is in the system. This means we don't need to protect it with permissions. 1905d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * @hide 1906d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana */ 1907d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana public void grantAppPermission(Account account, String authTokenType, int uid) { 1908382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null || authTokenType == null) { 1909382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana Log.e(TAG, "grantAppPermission: called with invalid arguments", new Exception()); 191031957f1badbb900bbfe211317e1ea992d650a72dFred Quintana return; 191131957f1badbb900bbfe211317e1ea992d650a72dFred Quintana } 1912d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana SQLiteDatabase db = mOpenHelper.getWritableDatabase(); 1913d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana db.beginTransaction(); 1914d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana try { 1915d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana long accountId = getAccountId(db, account); 1916d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (accountId >= 0) { 1917d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana ContentValues values = new ContentValues(); 1918d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana values.put(GRANTS_ACCOUNTS_ID, accountId); 1919d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana values.put(GRANTS_AUTH_TOKEN_TYPE, authTokenType); 1920d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana values.put(GRANTS_GRANTEE_UID, uid); 1921d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana db.insert(TABLE_GRANTS, GRANTS_ACCOUNTS_ID, values); 1922d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana db.setTransactionSuccessful(); 1923d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1924d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } finally { 1925d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana db.endTransaction(); 1926d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1927d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana cancelNotification(getCredentialPermissionNotificationId(account, authTokenType, uid)); 1928d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1929d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana 1930d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana /** 1931d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * Don't allow callers with the given uid permission to get credentials for 1932d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * account/authTokenType. 1933d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * <p> 1934d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * Although this is public it can only be accessed via the AccountManagerService object 1935d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * which is in the system. This means we don't need to protect it with permissions. 1936d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana * @hide 1937d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana */ 1938d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana public void revokeAppPermission(Account account, String authTokenType, int uid) { 1939382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana if (account == null || authTokenType == null) { 1940382601fc8babccee0d0b953ecd9bef745d126996Fred Quintana Log.e(TAG, "revokeAppPermission: called with invalid arguments", new Exception()); 194131957f1badbb900bbfe211317e1ea992d650a72dFred Quintana return; 194231957f1badbb900bbfe211317e1ea992d650a72dFred Quintana } 1943d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana SQLiteDatabase db = mOpenHelper.getWritableDatabase(); 1944d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana db.beginTransaction(); 1945d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana try { 1946d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana long accountId = getAccountId(db, account); 1947d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana if (accountId >= 0) { 1948d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana db.delete(TABLE_GRANTS, 1949d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana GRANTS_ACCOUNTS_ID + "=? AND " + GRANTS_AUTH_TOKEN_TYPE + "=? AND " 1950d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana + GRANTS_GRANTEE_UID + "=?", 1951d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana new String[]{String.valueOf(accountId), authTokenType, 1952d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana String.valueOf(uid)}); 1953d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana db.setTransactionSuccessful(); 1954d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1955d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } finally { 1956d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana db.endTransaction(); 1957d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1958d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana cancelNotification(getCredentialPermissionNotificationId(account, authTokenType, uid)); 1959d4a1d2e14297a3387fdb5761090961e714370492Fred Quintana } 1960603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana} 1961