1 /* 2 * Copyright (C) 2007 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.android.googleapps; 18 19 import com.google.android.googleapps.GoogleLoginCredentialsResult; 20 import com.google.android.googleapps.LoginData; 21 22 23 /** 24 * Central application service used by Google apps to acquire login 25 * credentials for all Google services. 26 * <p> 27 * See {@link GoogleLoginServiceHelper} and 28 * {@link GoogleLoginServiceSynchronousHelper} for convenience wrappers 29 * around the sequence of binding to the service and then 30 * making API calls. 31 */ 32 interface IGoogleLoginService { 33 /** 34 * Gets the list of Google Accounts the user has previously logged 35 * in to. Accounts are of the form "username@domain". 36 * <p> 37 * This method will return an empty array if the device doesn't 38 * know about any Google accounts (yet). In this case, if the 39 * caller is an application (rather than a background task), the 40 * typical next step is to call {@link #blockingGetCredentials} 41 * with a null account; this will return an Intent that, 42 * if run using {@link android.app.Activity#startSubActivity startSubActivity}, 43 * will prompt the user for username/password and ultimately 44 * return an authentication token for the desired service. 45 * 46 * @return The accounts. The array will be zero-length if the 47 * GoogleLoginService doesn't know about any accounts yet. 48 */ getAccounts()49 String[] getAccounts(); 50 51 /** 52 * @deprecated 53 * 54 * Now equivalent to <code>getAccount(false)</code>. 55 */ getPrimaryAccount()56 String getPrimaryAccount(); 57 58 /** 59 * Get the account to use on this device. 60 * 61 * @param requireGoogle true if you need the device's Google 62 * (non-hosted domain) account. 63 * 64 * @return username of the account 65 */ getAccount(boolean requireGoogle)66 String getAccount(boolean requireGoogle); 67 68 /** 69 * Retrieves the credentials for a given account and service 70 * <i>only if</i> the device already has a cached authentication token for that 71 * account/service. 72 * <p> 73 * This method will <i>not</i> do any network I/O, even in the case 74 * where we have no auth token for the specified service but we do 75 * have a password for the specified account. 76 * (Use {@link #blockingGetCredentials} if you do want to allow 77 * the GoogleLoginService to use the network to fetch a fresh 78 * auth token in this case.) 79 * <p> 80 * Note that the GoogleLoginService caches auth tokens 81 * indefinitely, but the tokens themselves may expire over time. 82 * Thus, the auth token returned by this method is <i>not</i> 83 * guaranteed to be valid (since we'd need to do network I/O to 84 * check that!) 85 * <p> 86 * The account and service parameters are the same as in 87 * the {@link #blockingGetCredentials} call. 88 * 89 * @return An authentication token for the desired username/service, 90 * or null if the device doesn't have a 91 * cached auth token for that username/service. 92 */ peekCredentials(String username, String service)93 String peekCredentials(String username, String service); 94 95 96 /** 97 * Retrieves the credentials for a given account and service. 98 * <p> 99 * This method will <b>either</b> 100 * <ol> 101 * <li> return an authentication token for the specified account/service 102 * <p> <b>or</b> 103 * <li> return an Intent which you (the caller) need to run 104 * yourself using {@link android.app.Activity#startSubActivity startSubActivity}, 105 * which will ultimately return the desired 106 * auth token to your <code>onActivityResult</code> method. 107 * <br> 108 * (Generally, that Intent will bring up a UI for the user to 109 * enter their username and password, but the 110 * IGoogleLoginService interface deliberately doesn't specify 111 * exactly what that Intent will do.) 112 * </ol> 113 * The {@link GoogleLoginCredentialsResult} class encapsulates these two 114 * possible results: either the <code>getCredentialsString</code> method will 115 * return an auth token (in case (1) above), or the 116 * <code>getCredentialsIntent</code> method will return the Intent you need 117 * to run to prompt the user (in case (2)). 118 * <p> 119 * This method will never return a GoogleLoginCredentialsResult 120 * object where <i>both</i> <code>getCredentialsString()</code> and 121 * <code>getCredentialsIntent()</code> return non-null. 122 * <p> 123 * Other notes: 124 * <ul> 125 * <li> In case (1) this method may block to do network I/O! 126 * Use {@link #peekCredentials} instead if you need to quickly check 127 * whether the device has a cached auth token for a given 128 * account/service. 129 * <p> 130 * <li> In case (2), if it's appropriate to interact with the user at 131 * the current time, the caller should run the returned Intent as 132 * a sub-activity. 133 * When that sub-activity returns, the resulting "extras" Bundle 134 * (which will be returned to the caller's <code>onActivityResult</code> 135 * method) will contain the following two mappings <i>if</i> we 136 * were able to successfully log in to the specified 137 * account/service: 138 * <ul> 139 * <li>key = {@link GoogleLoginServiceConstants#AUTHTOKEN_KEY 140 * GoogleLoginServiceConstants.AUTHTOKEN_KEY} 141 * <li>value = Auth token for the specified account/service (String) 142 * </ul> 143 * and 144 * <ul> 145 * <li>key = {@link GoogleLoginServiceConstants#AUTH_ACCOUNT_KEY 146 * GoogleLoginServiceConstants.AUTH_ACCOUNT_KEY} 147 * <li>value = Account name used to generate the above auth token (String), 148 * which will probably be useful if you initially 149 * called <code>blockingGetCredentials</code> with a null account name. 150 * </ul> 151 * <p> 152 * Note: if the caller's <code>onActivityResult</code> method is called with 153 * a null "extras" Bundle, or a resultCode of RESULT_CANCELED, 154 * that means that we weren't able to authenticate. 155 * Either the user bailed out without entering a 156 * username+password at all, or there was some failure during 157 * the authentication process. 158 * <p> 159 * <li>If your application simply wants to "log into an account 160 * without ever prompting the user", like in the (very common) 161 * case of a background task or sync adapter, you can simply 162 * handle case (2) by not doing anything at all (other than maybe 163 * displaying a "couldn't log in" status somewhere in your UI.) 164 * <p> 165 * <li>See {@link GoogleLoginServiceHelper#getCredentials 166 * GoogleLoginServiceHelper.getCredentials} for a static 167 * convenience wrapper around this entire sequence. 168 * </ul> 169 * 170 * @param account The account to obtain the credentials for. 171 * This should either be one of the accounts returned by 172 * the <code>getAccounts</code> call, or null. 173 * <br> 174 * The account will typically be null in the 175 * case where there the device doesn't know about 176 * any accounts yet, or also in the case where 177 * an application needs to log into a new account; 178 * a null account here guarantees that we'll 179 * need to prompt the user for username/password. 180 * <br> 181 * UI note: In the case where we return an Intent 182 * to prompt the user for username/password, that 183 * UI will automatically assume a domain name 184 * (usually "@gmail.com", but which may vary 185 * depending on the specified service) if the user 186 * enters a username with no domain. 187 * 188 * @param service The service to log in to, like "cl" (Calendar) 189 * or "mail" (GMail) or "blogger" (Blogger). 190 * (See the API documentation for your specific 191 * service to find out what service name to use 192 * here.) 193 * <br> 194 * If null, the resulting authentication token will 195 * be "non-compartmentalized" (and will work across 196 * all non-compartmentalized Google services.) 197 * 198 * @param notifyAuthFailure if true, we will put up a status bar 199 * notification if the attempt get the auth token 200 * over the network fails because the password is 201 * invalid (or because the password is blank). 202 * 203 * @return The results: either the requested credentials, 204 * or an Intent that your app can run to get them. 205 */ blockingGetCredentials( String username, String service, boolean notifyAuthFailure)206 GoogleLoginCredentialsResult blockingGetCredentials( 207 String username, String service, boolean notifyAuthFailure); 208 209 /** 210 * Invalidates the specified authentication token. The next time 211 * this token is requested it will be reauthenticated. 212 * <p> 213 * Background: the auth tokens returned from <code>peekCredentials()</code> or 214 * <code>blockingGetCredentials()</code> are <i>not</i> guaranteed to be 215 * valid, mainly because a token cached in the device's database may 216 * have expired since we last tried to use it. (Most auth tokens expire 217 * after some amount of time, but the GoogleLoginService itself can't tell 218 * when or if a given auth token will expire. Only the Google service 219 * your application talks to can say for sure whether a given auth token 220 * is still valid.) 221 * <p> 222 * So if you do get an authentication error (from your app's service) when 223 * using an auth token that came from the GoogleLoginService, you should 224 * tell the GoogleLoginService about it by passing the failed token to 225 * this method. After doing that, you can get a fresh token by making 226 * another <code>blockingGetCredentials()</code> call (or 227 * <code>getCredentials()</code> if using a helper class like 228 * <code>GoogleLoginServiceHelper</code>). 229 * 230 * @param authTokenToInvalidate The auth token to invalidate. 231 */ invalidateAuthToken(String authTokenToInvalidate)232 void invalidateAuthToken(String authTokenToInvalidate); 233 234 /** 235 * Returns the "Android ID", a 64-bit value unique to this device 236 * assigned when the device is first registered with Google. 237 * 238 * Returns 0 if the device is not registered, or if the Android ID 239 * is unavailable for any reason. This call never blocks for 240 * network activity. 241 */ getAndroidId()242 long getAndroidId(); 243 244 // -------------------------------------------------------- 245 // methods below this point require the 246 // com.google.android.googleapps.permission.ACCESS_GOOGLE_PASSWORD 247 // permission, and will fail if the caller does not have it. 248 // -------------------------------------------------------- 249 250 /** 251 * Try logging in to a new account. 252 * 253 * On calling, data should contain username, password, (optional) 254 * captcha token and answer. flags should be 0 to allow any 255 * account, or FLAG_GOOGLE_ACCOUNT to require a google account. 256 * 257 * The possible values of data.mStatus on return are described by 258 * the {@link LoginData.Status} enum. 259 * 260 * If status is CAPTCHA, the captcha token, data, and mime type 261 * fields will be filled in. 262 */ tryNewAccount(inout LoginData data)263 void tryNewAccount(inout LoginData data); 264 265 /** 266 * Save a new account to the database. data should be an object 267 * previously passed to tryNewAccount, with status SUCCESS. 268 */ saveNewAccount(in LoginData data)269 void saveNewAccount(in LoginData data); 270 271 /** 272 * Store an auth token into the database. Has no effect if 273 * account is not in the database. 274 */ saveAuthToken(String username, String service, String authToken)275 void saveAuthToken(String username, String service, String authToken); 276 277 /** 278 * Try to obtain an authtoken for the username and service in 279 * data, using the password in data. If successful, save the 280 * password in the database (and return the authtoken). 281 * 282 * If the password in data is null, erases the password and all 283 * authtokens for the account from the database. 284 * 285 * username must already exist in the database, or a status of 286 * BAD_REQUEST will be returned. 287 */ updatePassword(inout LoginData data)288 void updatePassword(inout LoginData data); 289 290 /** 291 * Returns true if the given username/password match one stored in 292 * the login service. This does <i>not</i> do any network 293 * activity; it does not check that the password is valid on 294 * Google's servers, only that it matches what is stored on the 295 * device. 296 */ verifyStoredPassword(String username, String password)297 boolean verifyStoredPassword(String username, String password); 298 299 // -------------------------------------------------------- 300 // methods below this point exist primarily for automated tests. 301 // -------------------------------------------------------- 302 303 /** 304 * Add a new username/password pair to the Google Login Service. 305 * Does not test to see if they are valid; just puts them directly 306 * in the database. 307 * 308 * @param account the username (email address) of the account to add 309 * @param password the password for this new account 310 */ saveUsernameAndPassword(String username, String password, int flags)311 void saveUsernameAndPassword(String username, String password, int flags); 312 313 /** 314 * Remove an account and all its authtokens from the database. 315 * 316 * @param account the account to remove 317 */ deleteOneAccount(String username)318 void deleteOneAccount(String username); 319 320 /** 321 * Remove all accounts and authtokens from the database. 322 */ deleteAllAccounts()323 void deleteAllAccounts(); 324 325 /** 326 * Cause the device to register and get an android ID. 327 * @return If LoginData.Status were an int we could return that. Instead 328 * we return: 329 * 0 - success 330 * 1 - login failure (caller should ask for a new password) 331 * 2 - NOT IMPLEMENTED - CAPTCHA required? 332 * -1 - network or other transient failure (caller should try again, with a backoff) 333 */ waitForAndroidId()334 int waitForAndroidId(); 335 336 // TODO: The aidl compiler might let you define constants (static 337 // member variables) one of these days, rather than just letting 338 // you declare member functions. 339 // 340 // When/if that happens, I should consider adding a section to 341 // this aidl file for "Miscellaneous constants used by the 342 // GoogleLoginService and related helper classes", containing the 343 // constants currently found in the GoogleLoginServiceConstants 344 // class (which can then be deleted.) 345 } 346