117250429db16553b59d5df5e358f71406dd2b322Andrew Stadler/* 217250429db16553b59d5df5e358f71406dd2b322Andrew Stadler * Copyright (C) 2009 The Android Open Source Project 317250429db16553b59d5df5e358f71406dd2b322Andrew Stadler * 417250429db16553b59d5df5e358f71406dd2b322Andrew Stadler * Licensed under the Apache License, Version 2.0 (the "License"); 517250429db16553b59d5df5e358f71406dd2b322Andrew Stadler * you may not use this file except in compliance with the License. 617250429db16553b59d5df5e358f71406dd2b322Andrew Stadler * You may obtain a copy of the License at 717250429db16553b59d5df5e358f71406dd2b322Andrew Stadler * 817250429db16553b59d5df5e358f71406dd2b322Andrew Stadler * http://www.apache.org/licenses/LICENSE-2.0 917250429db16553b59d5df5e358f71406dd2b322Andrew Stadler * 1017250429db16553b59d5df5e358f71406dd2b322Andrew Stadler * Unless required by applicable law or agreed to in writing, software 1117250429db16553b59d5df5e358f71406dd2b322Andrew Stadler * distributed under the License is distributed on an "AS IS" BASIS, 1217250429db16553b59d5df5e358f71406dd2b322Andrew Stadler * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1317250429db16553b59d5df5e358f71406dd2b322Andrew Stadler * See the License for the specific language governing permissions and 1417250429db16553b59d5df5e358f71406dd2b322Andrew Stadler * limitations under the License. 1517250429db16553b59d5df5e358f71406dd2b322Andrew Stadler */ 1617250429db16553b59d5df5e358f71406dd2b322Andrew Stadler 1717250429db16553b59d5df5e358f71406dd2b322Andrew Stadlerpackage com.android.email.service; 1817250429db16553b59d5df5e358f71406dd2b322Andrew Stadler 19bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport com.android.email.activity.setup.AccountSetupBasics; 20bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport com.android.emailcommon.AccountManagerTypes; 21bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport com.android.emailcommon.CalendarProviderStub; 22bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport com.android.emailcommon.provider.EmailContent; 23bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 24bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport android.accounts.AbstractAccountAuthenticator; 25bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport android.accounts.Account; 26bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport android.accounts.AccountAuthenticatorResponse; 27bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport android.accounts.AccountManager; 28bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport android.accounts.NetworkErrorException; 29bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport android.app.Service; 30bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport android.content.ContentResolver; 31bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport android.content.Context; 32bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport android.content.Intent; 33bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport android.os.Bundle; 34bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport android.os.IBinder; 35bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport android.provider.ContactsContract; 36bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 3717250429db16553b59d5df5e358f71406dd2b322Andrew Stadler/** 38bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * A very basic authenticator service for EAS. At the moment, it has no UI hooks. When called 39bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * with addAccount, it simply adds the account to AccountManager directly with a username and 40bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * password. 4117250429db16553b59d5df5e358f71406dd2b322Andrew Stadler */ 42bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookpublic class EasAuthenticatorService extends Service { 43bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public static final String OPTIONS_USERNAME = "username"; 44bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public static final String OPTIONS_PASSWORD = "password"; 45bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public static final String OPTIONS_CONTACTS_SYNC_ENABLED = "contacts"; 46bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public static final String OPTIONS_CALENDAR_SYNC_ENABLED = "calendar"; 47bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public static final String OPTIONS_EMAIL_SYNC_ENABLED = "email"; 48bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 49bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook class EasAuthenticator extends AbstractAccountAuthenticator { 50bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook private Context mContext; 51bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 52bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public EasAuthenticator(Context context) { 53bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook super(context); 54bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mContext = context; 55bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 56bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 57bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook @Override 58bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public Bundle addAccount(AccountAuthenticatorResponse response, String accountType, 59bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook String authTokenType, String[] requiredFeatures, Bundle options) 60bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook throws NetworkErrorException { 61bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // There are two cases here: 62bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // 1) We are called with a username/password; this comes from the traditional email 63bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // app UI; we simply create the account and return the proper bundle 64bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (options != null && options.containsKey(OPTIONS_PASSWORD) 65bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook && options.containsKey(OPTIONS_USERNAME)) { 66bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook final Account account = new Account(options.getString(OPTIONS_USERNAME), 67bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook AccountManagerTypes.TYPE_EXCHANGE); 68bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook AccountManager.get(EasAuthenticatorService.this).addAccountExplicitly( 69bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook account, options.getString(OPTIONS_PASSWORD), null); 70bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 71bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // Set up contacts syncing. ExchangeService will use info from ContentResolver 72bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // to determine syncability of Contacts for Exchange 73bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook boolean syncContacts = false; 74bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (options.containsKey(OPTIONS_CONTACTS_SYNC_ENABLED) && 75bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook options.getBoolean(OPTIONS_CONTACTS_SYNC_ENABLED)) { 76bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook syncContacts = true; 77bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 78bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook ContentResolver.setIsSyncable(account, ContactsContract.AUTHORITY, 1); 79bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook ContentResolver.setSyncAutomatically(account, ContactsContract.AUTHORITY, 80bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook syncContacts); 81bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 82bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // Set up calendar syncing, as above 83bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook boolean syncCalendar = false; 84bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (options.containsKey(OPTIONS_CALENDAR_SYNC_ENABLED) && 85bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook options.getBoolean(OPTIONS_CALENDAR_SYNC_ENABLED)) { 86bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook syncCalendar = true; 87bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 88bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook ContentResolver.setIsSyncable(account, CalendarProviderStub.AUTHORITY, 1); 89bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook ContentResolver.setSyncAutomatically(account, CalendarProviderStub.AUTHORITY, 90bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook syncCalendar); 91bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 92bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // Set up email syncing, as above 93bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook boolean syncEmail = false; 94bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (options.containsKey(OPTIONS_EMAIL_SYNC_ENABLED) && 95bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook options.getBoolean(OPTIONS_EMAIL_SYNC_ENABLED)) { 96bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook syncEmail = true; 97bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 98bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook ContentResolver.setIsSyncable(account, EmailContent.AUTHORITY, 1); 99bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook ContentResolver.setSyncAutomatically(account, EmailContent.AUTHORITY, 100bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook syncEmail); 101bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 102bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook Bundle b = new Bundle(); 103bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook b.putString(AccountManager.KEY_ACCOUNT_NAME, options.getString(OPTIONS_USERNAME)); 104bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook b.putString(AccountManager.KEY_ACCOUNT_TYPE, AccountManagerTypes.TYPE_EXCHANGE); 105bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return b; 106bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // 2) The other case is that we're creating a new account from an Account manager 107bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // activity. In this case, we add an intent that will be used to gather the 108bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // account information... 109bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } else { 110bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook Bundle b = new Bundle(); 111bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook Intent intent = 112bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook AccountSetupBasics.actionSetupExchangeIntent(EasAuthenticatorService.this); 113bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response); 114bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook b.putParcelable(AccountManager.KEY_INTENT, intent); 115bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return b; 116bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 117bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 118bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 119bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook @Override 120bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public Bundle confirmCredentials(AccountAuthenticatorResponse response, Account account, 121bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook Bundle options) { 122bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return null; 123bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 124bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 125bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook @Override 126bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public Bundle editProperties(AccountAuthenticatorResponse response, String accountType) { 127bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return null; 128bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 129bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 130bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook @Override 131bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public Bundle getAuthToken(AccountAuthenticatorResponse response, Account account, 132bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook String authTokenType, Bundle loginOptions) throws NetworkErrorException { 133bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return null; 134bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 135bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 136bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook @Override 137bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public String getAuthTokenLabel(String authTokenType) { 138bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // null means we don't have compartmentalized authtoken types 139bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return null; 140bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 141bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 142bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook @Override 143bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public Bundle hasFeatures(AccountAuthenticatorResponse response, Account account, 144bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook String[] features) throws NetworkErrorException { 145bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return null; 146bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 147bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 148bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook @Override 149bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public Bundle updateCredentials(AccountAuthenticatorResponse response, Account account, 150bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook String authTokenType, Bundle loginOptions) { 151bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return null; 152bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 153bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 154bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 155bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 156bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook @Override 157bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public IBinder onBind(Intent intent) { 158bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (AccountManager.ACTION_AUTHENTICATOR_INTENT.equals(intent.getAction())) { 159bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return new EasAuthenticator(this).getIBinder(); 160bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } else { 161bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return null; 162bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 163bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 16417250429db16553b59d5df5e358f71406dd2b322Andrew Stadler} 165